pythonic-イテレータ機能-itertools

理解

Pythonモジュールは、itertoolsの数が提供するメモリ効率的な反復子を救う起こすには大きすぎるデータの量について何かを解決するために、具体的には、メモリ・オーバーフロー(のOutOfMemory)シーンを。
我々は通常、このサイクルの大半を使用しています。

# while 循环: 求1+2+...100
s, i = 0, 1 
while i <= 100:
    s += i 
    i += 1
print('while-loop: the some of 1+2+..100 is:', s)


# for 循环
s = 0 
for i in range(101):
    s += i
print('for-loop: the some of 1+2+..100 is:', s)
while-loop: the some of 1+2+..100 is: 5050
for-loop: the some of 1+2+..100 is: 5050

しかし、データの量は次のように、それはクール特に大きいので、itertoolsの導入、イテレータ場合は遅延ロードの思考

共通API

  • 鎖()
  • GROUPBY()
  • 蓄積()
  • 圧縮()
  • takewhile()
  • Islice()
  • 繰り返す()

チェーンステッチ要素

  • オブジェクトは、より大きなイテレータを形成する、互いに反復のセットです。
# join / split 
s = "If you please draw me a sheep?"

s1 = s.split()

s2 = "-".join(s1)

print("split->:", s1)
print("join->:", s2)
split->: ['If', 'you', 'please', 'draw', 'me', 'a', 'sheep?']
join->: If-you-please-draw-me-a-sheep?
import itertools 
# chain
s = itertools.chain(['if', 'you'], ['please draw', 'me', 'a'], 'shape')
s
<itertools.chain at 0x1d883602240>
list(s)
['if', 'you', 'please draw', 'me', 'a', 's', 'h', 'a', 'p', 'e']

見つけるのは難しいことではありません、これはまあイテレータで、何も本当に。ほとんどのように参加します。それはそれのメモリを節約する方法ですので、実際に簡単なイテレータのアイデアで、効率的なメモリを節約し、メモリに一つの要素を読みますうん

def chain(*iterables):
    for iter_ in iterables:
        for elem in iter_:
            yield elem

GROUPBY隣人

  • に選び出しイテレータ隣接繰り返しエレメント
# 只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key
for key, group in itertools.groupby('AAABBBCCAAAdde'):
    print(key, list(group))
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
d ['d', 'd']
e ['e']
# 忽略大小写
for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
    print(key, list(group))
A ['A', 'a', 'a']
B ['B', 'B', 'b']
C ['c', 'C']
A ['A', 'A', 'a']

累積ロールアップを蓄積

list(itertools.accumulate([1,2,3,4,5], lambda x,y: x*y))
[1, 2, 6, 24, 120]
# 伪代码
def accumulate(iterable, func=None, *, initial=None):
    iter_ = iter(iterable)
    ret = initial
    # 循环迭代
    if initial is None:
        try:
            ret = next(iter_)
        except StopIteration:
            return 
    yield ret
    # 遍历每个元素, 调用传入的函数去处理
    for elem in iter_:
        ret = func(elem)
        yield ret
        

フィルタを圧縮

list(itertools.compress('youge', [1,0,True,3]))
['y', 'u', 'g']
def compress(data, selectors):
    for d, s in zip(data, selectors):
        if s:
            return d
        
# demo
for data, key in zip([1,2], 'abcd'):
    print(data,key)
    if key:
        print(data)
1 a
1
2 b
2
# Pythonic
def compress(data, selectors):
    return (d for d, s in zip(data, selectors) if s)

# tset
ret = compress(['love', 'you', 'forever'], ['love', None, 'dd', 'forever'])
print(ret)
print(list(ret))
<generator object compress.<locals>.<genexpr> at 0x000001D8831498E0>
['love', 'forever']

ジェネレータ

  • ITERは、発電機の対象となるクラス()メソッドとnext()メソッドで達成しました
  • キーワードが表示される利回りタプルまたはファンクション・ジェネレータ:コードの2つの形式があります。

ジップ

  • また「延長機能」と呼ばれる最短一致が停止しているスプライス要素に対応する位置、

テイクしばらく

  • takewhile:条件が満たさ出ていないと、反復継続し、条件が返され、反復ターン
# takewhile
s1 = list(itertools.takewhile(lambda x:x<=2, [0,3,2,1,-1,3,0]))
print(s1)

s2 = list(itertools.takewhile(lambda x:x<5, [1,4,6,4,1,3]))
print(s2)

# dropwhile
s3 = list(itertools.filterfalse(lambda x:x%2==0, range(10)))
print(s3)
[0]
[1, 4]
[1, 3, 5, 7, 9]
def take_while(condition, iter_obj):
    for elem in iter_obj:
        if conditon(elem):
            yield elem
        else:
            break

dropwhile:復帰の条件を満たしていません

isliceスライス

# 普通的切片,也是要先全部读入内存
# 注意是深拷贝的哦
l = [1,2,3,4,5]
print(l[::--1])

# generator 方式
# 默认的 start, stop, step, 只能传0或正数, 但可以自己改写的呀
list(itertools.islice(l, 0,3,1))

s = slice(3,4,5) # 只接收3个参数
s.start
s.stop
[1, 2, 3, 4, 5]
[1, 2, 3]
3
4
import sys

def slice(iter_obj, *args):
    s = slice(*args)
    
    start = s.start or 0 
    stop = s.stop or sys.maxsize # 很大的常量
    step = s.step or 1 
    # 构成可迭代的对象(下标)
    iter_ = iter(range(start, stop, step))
    try:
        next_i = next(iter_)
    except StopIteration:
#         for i, elem n zip(range(start), iter_obj):
            pass
        return 
    try:
        i, elem in enumerate(iter_obj):
            if i == next_i:
                yield elem
                next_i = next(elem)
    except StopIteration:
        pass
    
[1, 2, 3, 4, 5]

繰り返す

list(itertools.repeat(['youge'], 3))
[['youge'], ['youge'], ['youge']]
def repeat(obj, times=None):
    if times is None:
        while True:  # 一直返回
            yield obj
    else:
        for i in range(times):
            yield obj
        

おすすめ

転載: www.cnblogs.com/chenjieyouge/p/11795994.html