python-----Advanced Iterators

python笔记--9.5
map/reduce
map()和reduce()均为Python内置的函数

map()函数接受两个参数,一个是函数,一个是Iterable。map将传入的函数一次作用到序列的每一个元素,并把结果作为新的Iterator返回。
例如:
def f(x):
return x*x
r=map(f,[1,2,3,4,5,6,7,8,9])
print(list(r))
result:
[1,4,9,16,25,36,49,64,81]

又如:
print(list(map(str,[1,2,3,4,5,6,7,8,9])))
result:
[‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘]

reduce()把一个函数作用在一个序列[x1,x2,x3,...]上,这个函数接收两个参数,reduce把结果继续和序列的下一个元素做累积运算。
如:
reduce(f,[x1,x2,x3,x4])=f(f(f(x1,x2),x3),x4)
需求1:将[1,2,3,4,5]转化成12345输出

from functools import reduce
def fn(x,y):
return 10*x+y
reduce(fn,[1,2,3,4,5])

需求2:将字符串‘13579’转换成数字13579输出
from functools import reduce
def str2int(s):
def fn(x,y):
return x*10+y
def char2num(s):
retuen return {‘0‘: 0, ‘1‘: 1, ‘2‘: 2, ‘3‘: 3, ‘4‘: 4, ‘5‘: 5, ‘6‘: 6, ‘7‘: 7, ‘8‘: 8, ‘9‘: 9}[s]
return reduce(fn,map(char2num,s))
需求3:将字符串‘123.456’转换成123.456
def str2float(s):
def fn(x,y):
return x*10+y
def fx(x,y):
return x/10+y
def char2num(s):
return {‘0‘:0,‘1‘:1,‘2‘:2,‘3‘:3,‘4‘:4,‘5‘:5,‘6‘:6,‘7‘:7,‘8‘:8,‘9‘:9}[s]
L=s.split(‘.‘,1)
return reduce(fn,map(char2num,L[0]))+reduce(fx,map(char2num,L[1][-1::-1]))/10
----------------------------------------------------------------------------------------------------------------
生成表达式(Generator Expression)
像是一个生成函数,但是不是函数
unique_characters={‘E‘,‘D‘,‘M‘,‘O‘,‘N‘,‘S‘,‘R‘,‘Y‘}
gen=(ord(c) for c in unique_characters)
next(gen)#69
next(gen)#68

tuple(ord(c) for c in unique_characters)
print(tuple)#(69,68,77,79,78,83,82,89)

使用生成函数完成相同任务:
def ord_map(a_string):
for c in a_string:
yield ord(c)
gen=ord_map(unique_characters)

---------------------------------------------------------------------------------
排列组合问题的计算:
import itertools
在itertools中包含很多有意思的东西,permutations()就是包括在其中的寻找所有排列组合的有趣的方法

import itertools
perms=itertools.permutations([1,2,3],2)
next(perms)#(1,2)
next(perms)#(1,3)
next(perms)#(2,1)
next(perms)#(2,3)
next(perms)#(3,1)
next(perms)#(3,2)

permutations()接收两个参数,一个是一个序列,一个是一个int整数,表示在每个组合中你想要的元素的个数
permutations()接收的不一定必须是一个list,可以是任意序列,甚至可以是一个string
例如:
import itertools
perms=itertools.permutations(‘ABC‘,3)
print(list(perms))
‘‘‘
[
(‘A‘,‘B‘,‘C‘),(‘A‘,‘C‘,‘B‘),
(‘B‘,‘A‘,‘C‘),(‘B‘,‘C‘,‘A‘),
(‘C‘,‘A‘,‘B‘),(‘C‘,‘B‘,‘A‘)
]
‘‘‘
----------------------------------------------
在itertools模块中的另一个有趣的方法

import itertools
list(itertools.product(‘ABC‘,123‘))
[
(‘A‘, ‘1‘), (‘A‘, ‘2‘), (‘A‘, ‘3‘),
(‘B‘, ‘1‘), (‘B‘, ‘2‘), (‘B‘, ‘3‘),
(‘C‘, ‘1‘), (‘C‘, ‘2‘), (‘C‘, ‘3‘)
]

list(itertools.combinations(‘ABC‘,2))
[(‘A‘,‘B‘),(‘A‘,‘C‘),(‘B‘,‘C‘)]

-------------------------------------------------
引例:
names=list(open(‘favorite-people.txt‘,encoding=‘utf-8‘))
print(names)
[‘Dora\n‘, ‘Ethan\n‘, ‘Wesley\n‘, ‘John\n‘, ‘Anne\n‘,
‘Mike\n‘, ‘Chris\n‘, ‘Sarah\n‘, ‘Alex\n‘, ‘Lizzie\n‘]

list(open(filename))将会以list的形式返回文本文件中的每一行数据,但是‘\n‘也包含在其中一起返回

使用rstrip()方法可以去掉尾部的‘\n‘
names=[name.rstrip() for name in names]
print(names)
[‘Dora‘, ‘Ethan‘, ‘Wesley‘, ‘John‘, ‘Anne‘,
‘Mike‘, ‘Chris‘, ‘Sarah‘, ‘Alex‘, ‘Lizzie‘]

使用sorted()方法可以对list进行排序,默认按照字母表顺序排序
names=sorted(names)
print(names)
[‘Alex‘, ‘Anne‘, ‘Chris‘, ‘Dora‘, ‘Ethan‘,
‘John‘, ‘Lizzie‘, ‘Mike‘, ‘Sarah‘, ‘Wesley‘]

sorted()方法可以接收一个用于指示排序方法的key参数
names=sorted(names,key=len)
print(names)
[‘Alex‘, ‘Anne‘, ‘Dora‘, ‘John‘, ‘Mike‘,
‘Chris‘, ‘Ethan‘, ‘Sarah‘, ‘Lizzie‘, ‘Wesley‘]
即按照名字长短进行排序

那么如何使用itertools来实现相同的操作?
import itertools
groups=itertools.groupby(names,len)

itertools.groupby方法接收两个参数,一个序列和一个key方法,并且返回一个生成组对的迭代器(iterator)。每个组对(pair)包含

key_function(each item)的结果和另一个迭代器(包含所有有相同key值的元素)
list(groups)操作可得到结果如下:
[(4, <itertools._grouper object at 0x00BA8BF0>),
(5, <itertools._grouper object at 0x00BB4050>),
(6, <itertools._grouper object at 0x00BB4030>)]

下面我尝试来遍历:
groups=itertools.groupby(name,len)
for name_length,name_iter in groups:
print(‘Names with {0:d} letters:‘.format(name_length))
for name in name_iter:
print(name)

可以得到如下结果:
Names with 4 letters:
Alex
Anne
Dora
John
Mike
Names with 5 letters:
Chris
Ethan
Sarah
Names with 6 letters:
Lizzie
Wesley

注意:itertools.groupby()方法只有在输入的序列已经被排序后才有效,比如在此例中用len进行分组可行是因为在之前我们已经对names进行了

sorted(names,key=len)

----------------itertools.chain()-------------------------------------
list(range(0,3))#[0,1,2]
list(range(10,13))#[10,11,12]

list(itertools.chain(range(0,3),range(10,13)))#[0,1,2,10,11,12]
itertools.chain()方法可以接收任意数量的迭代器,可以把他们按照传入的顺序连接起来

-------------zip()--------------------------------------------
list(zip(range(0,3),range(10,13)))#[(0,10),(1,11),(2,12)]
list(zip(range(0,3),range(10,13),range(20,23)))#[(0, 10, 20), (1, 11, 21), (2, 12, 22)]
zip()方法接收任意数量的序列,返回所有序列的第一个元素构成的元组,第二个元素构成的元组.....

list(zip(range(0, 3), range(10, 14))) #[(0,10),(1,11),(2,12)]
zip()方法在最短的序列结束时停止,如上例所述。

list(itertools.zip_longest(range(0,3),range(10,14))) #[(0, 10), (1, 11), (2, 12), (None, 13)]
但是itertools.zip_longest()方法在最长序列结束后结束,短序列没有值与之对应的用None填充

-------------------------------alphametics solver(算术谜题解法)------------------------------------

characters=(‘S‘, ‘M‘, ‘E‘, ‘D‘, ‘O‘, ‘N‘, ‘R‘, ‘Y‘)
guess=(‘1‘, ‘2‘, ‘0‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘)
tuple(zip(characters,guess))
返回结果:
((‘S‘, ‘1‘), (‘M‘, ‘2‘), (‘E‘, ‘0‘), (‘D‘, ‘3‘),
(‘O‘, ‘4‘), (‘N‘, ‘5‘), (‘R‘, ‘6‘), (‘Y‘, ‘7‘))
dict(zip(character,guess))
返回结果:
{‘E‘: ‘0‘, ‘D‘: ‘3‘, ‘M‘: ‘2‘, ‘O‘: ‘4‘,
‘N‘: ‘5‘, ‘S‘: ‘1‘, ‘R‘: ‘6‘, ‘Y‘: ‘7‘}

算术谜题解法使用了这种技术来创建一个字典将puzzle里面的字母映射为解决方案里的数字。

characters=tuple(ord(c) for c in sorted_characters)
digits=tuple(ord(c) for c in ‘0123456789‘)
...
for guess in itertools.permutations(digits,len(characters)):
...
equation=puzzle.translate(dict(zip(characters,guess)))
-------------下面先解释一下translate()方法-----------------------------
在Python中strings有许多种方法,包括lower(),count(),format()等,现在想要介绍一种很少见但功能强大的方法:translate()
translate_table={ord(‘A‘):ord(‘O‘)}
print(translate_table) #{65:79}
‘MARK‘.translate(translate_table) #‘MORK‘

字符串的转换方法需要一个转换表(translate_table),就是将一个字符映射为另一个字符的字典,当然说字符并不是很准确,应该说是byte
bytes在Python3中是整形(integer),ord()方法返回一个字符的ASCII值(A-Z:65-90)
作用在字符串上的translate()方法接受一个转换表(translate_table),并将该字符串在该表中进行运行,替换掉所有在转换表中出现过的key

值,替换为其对应的值。(本例中,translate MARK to MORK)
-------------------------------------------------------------

这与解决字母算术难题有什么关系吗?请看如下:
characters=tuple(ord(c) for c in ‘SMEDONRY‘)
print(character) #(83, 77, 69, 68, 79, 78, 82, 89)
guess=tuple(ord(c) for c in ‘91570682‘)
print(guess) #(57, 49, 53, 55, 48, 54, 56, 50)
translate_table=dict(zip(character,guess))
print(translate_table) #{68: 55, 69: 53, 77: 49, 78: 54, 79: 48, 82: 56, 83: 57, 89: 50}

‘SEND+MORE==MONEY‘.translate(translate_table) #‘9567+1085==10652‘

-----------------------将任意字符串作为Python表达式求值---------------------------------
eval(‘1+1==2‘)#True
eval(‘1+1=3‘)#False
eval(‘9576+1085==10652‘)#True

eval()方法远不止于布尔型的表达式
eval(‘"A"+"B"‘)#‘AB‘
eval(‘"Mark".translate({65:79})‘)#MORK
eval(‘"AAAAA".count("A")‘)#5
eval(‘["*"]*5‘)#[‘*‘,‘*‘,‘*‘,‘*‘,‘*‘]

x=5
eval(‘x*5‘)#25
eval(‘pow(x,2)‘)#25

import math
eval(‘math.sqrt(x)‘)#2.2360679774997898

-----------------------------------------how to solve alphametic puzzles-------------------------------------------
1,find all letters in the puzzle :re.findall(),return a list
2,find all the unique letters in the puzzle:with sets and the set()function,return a set;with ‘‘.join()function join words

together;with set()to get seperate letters
3,check if there are more than 10 unique letters:with an assert statement(meaning that the puzzle if definitely unsolvable)
4,Convert the letters to their ASCII equivalents:with a generator object(unique_character={ord(c) for c in unique_characters})
5,calculates all the possible solutions:with the itertools.permutation()function
6,convert each possible solution to a Python expression:with translate()string method
7,test each possible solution by evaluating the Python expression:with eval()function
8,return the first solution that evaluates to True

---------------------codes----------------------------------------------
import re
import itertools

def solve(puzzle):
words = re.findall(‘[A-Z]+‘, puzzle.upper())
unique_characters = set(‘‘.join(words))
assert len(unique_characters) <= 10, ‘Too many letters‘
first_letters = {word[0] for word in words}
n = len(first_letters)
sorted_characters = ‘‘.join(first_letters) + \
‘‘.join(unique_characters - first_letters)
characters = tuple(ord(c) for c in sorted_characters)
digits = tuple(ord(c) for c in ‘0123456789‘)
zero = digits[0]
for guess in itertools.permutations(digits, len(characters)):
if zero not in guess[:n]:
equation = puzzle.translate(dict(zip(characters, guess)))
if eval(equation):
return equation

if __name__ == ‘__main__‘:
import sys
for puzzle in sys.argv[1:]:
print(puzzle)
solution = solve(puzzle)
if solution:
print(solution)

时间: 2024-08-22 19:32:33

python-----Advanced Iterators的相关文章

[Python] Advanced features

Slicing 12345 L[:10:2] # [0, 2, 4, 6, 8]L[::5] # 所有数,每5个取一个# [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] L[:] # copy L Iterating 12 for x, y in [(1, 1), (2, 4), (3, 9)]: print(x, y) List Comprehension A list compreh

Supporting Python 3(支持python3)——使用现代的风格改善你的代码

使用现代的风格来改善你的代码 一旦你已经添加了Python 3的支持,你将改成使用Python的新的函数来改进的代码.Once you have added Python 3 support you have a chance to use the newer features of Python to improve your code. Many of the things mentioned in this chapter are in fact possible to do even b

Python:迭代器 Iterator

迭代在很多语言中都有存在,在c++中,大家更加推崇使用迭代而不是下标的方式来访问数据,下面我们来看看python中的迭代. python中我们可以使用迭代来遍历list,dirc,甚至file,让我们先来以最简单的方式来认识下迭代: list = [1,2,3]for i in list: #似乎和c++的  for(auto iter:vec){}很像 dosomething 在c++中我们可以对iterator进行加减操作,来移动迭代器,那python中是如何实现的呢?查阅python 文档

Iterator Protocol - Python 描述符协议

1 Iterator Protocol - Python 描述符协议 2 3 先看几个有关概念, 4 iterator 迭代器, 5 一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多的元素可返回的时候 raises StopIteration 的对象, 6 被称为 iterator(迭代器). 7 在 python 中, 迭代器 'iterator' 同时也实现了 __iter__ 方法, 故 iterators are iterable. 8 经典迭代器

Dive into python3

Table of Contents What’s New in “Dive Into Python 3” a.k.a. “the minus level” Installing Python Diving In Which Python Is Right For You? Installing on Microsoft Windows Installing on Mac OS X Installing on Ubuntu Linux Installing on Other Platforms U

共享我收藏的一些课程【百度云】

人艰不拆你懂的. 很多资源是我自己下的,然后再上传,也有些是转存的,感谢那些分享的人~ 可能会夹杂一些 其他 Mooc 或是公开课的东西,请善用 ctrl+f . 网盘地址:http://pan.baidu.com/s/1c0GfnZ6 内容: (点击课程号可跳转) startup-001 创业项目工程 ,Startup Engineering sdn-001 软件定义网络,Software Defined Network publicspeak-001 公众演讲,Introduction to

[it-ebooks]电子书列表

#### it-ebooks电子书质量不错,但搜索功能不是很好 #### 格式说明  [ ]中为年份      ||  前后是标题和副标题  #### [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Objective-C to develop iPhone games http://it-ebooks.info/book/3544/ Learning Web App Developmen

(转) [it-ebooks]电子书列表

[it-ebooks]电子书列表 [2014]: Learning Objective-C by Developing iPhone Games || Leverage Xcode and Objective-C to develop iPhone games http://it-ebooks.info/book/3544/Learning Web App Development || Build Quickly with Proven JavaScript Techniques http://

Python标准模块--Iterators和Generators

1 模块简介 当你开始使用Python编程时,你或许已经使用了iterators(迭代器)和generators(生成器),你当时可能并没有意识到.在本篇博文中,我们将会学习迭代器和生成器是什么.当然,我们也会了解如何创建它们,在我们需要的时候,就可以创建属于我们自己的迭代器和生成器. 2 模块使用 2.1 迭代器 迭代器是一个允许你在一个容器上进行迭代的对象.Python的迭代器主要通过两个方法实现:__iter__和__next__.__iter__要求你的容器支持迭代.它会返回迭代器对象本

Python高级特性(1):Iterators、Generators和itertools(转)

译文:Python高级特性(1):Iterators.Generators和itertools [译注]:作为一门动态脚本语言,Python 对编程初学者而言很友好,丰富的第三方库能够给使用者带来很大的便利.而Python同时也能够提供一些高级的特性方便用户使用更为复杂的数据结构.本系 列文章共有三篇,本文是系列的第一篇,将会介绍迭代器.生成器以及itertools模块的相关用法.由于作者 Sahand Saba 列举的示例中有诸多专业的数学相关内容,因此翻译中有诸多不妥之处请大家指出,非常感谢