it-swarm-tr.com

Yineleyici, yinelenebilir ve yinelemenin tam olarak nedir?

Python'da "yinelemeli", "yineleyici" ve "yinelemenin" en temel tanımı nedir?

Birden çok tanım okudum, ancak tam anlamıyla hala içine dalmayacak gibi tanımlayamıyorum.

Birisi lütfen mesleği açısından 3 tanım konusunda bana yardımcı olabilir mi?

383
thechrishaddad

Yineleme , bir nesnenin her birini arka arkaya almak için kullanılan genel bir terimdir. Herhangi bir döngü, bir öğe grubunu gözden geçirmek için, açık veya örtülü kullandığınızda, bu yinelemedir.

Python'da, yinelenebilir ve yineleyici belirli anlamlara sahiptir.

Bir yinelenebilir , yineleyici döndüren __iter__ yöntemine sahip bir nesnedir. , veya sıfırdan başlayarak sıralı dizinleri alabilen bir __getitem__ yöntemini tanımlar (ve dizinler artık geçerli olmadığında IndexError değerini yükseltir). Yani bir yinelenebilir , bir yineleyici öğesinden alabileceğiniz bir nesnedir.

Bir yineleyici , next (Python 2) veya __next__ (Python 3) yöntemiyle bir nesnedir.

Python'da bir for döngüsü veya map veya liste anlama vb. Kullandığınızda, her öğeyi yineleyiciden almak için otomatik olarak next yöntemi çağrılır. ), böylece yineleme sürecinden geçiyor.

Öğrenmeye başlamak için iyi bir yer, öğreticinin yineleyiciler bölümü ve standart türler sayfasının yineleyici türleri bölümü olacaktır. Temel bilgileri anladıktan sonra, İşlevsel Programlama NASIL'ın yineleyiciler bölümünü deneyin.

454
agf

İşte Python sınıflarını öğretirken kullandığım açıklama:

BİR ITERABLE:

  • üzerine konulabilecek herhangi bir şey (örneğin, bir dize veya dosya üzerinde döngü kurabilirsiniz) veya
  • for-döngüsünün sağ tarafında görünebilecek herhangi bir şey: for x in iterable: ... veya
  • bir ITERATOR döndürecek iter() ile arayabileceğiniz herhangi bir şey: iter(obj) veya
  • taze bir ITERATOR döndüren __iter__ öğesini tanımlayan bir nesne veya dizine alınmış arama için uygun bir __getitem__ yöntemine sahip olabilir.

Bir ITERATOR bir nesnedir:

  • yineleme sırasında nerede olduğunu hatırlayan bir devletle,
  • __next__ yöntemiyle şu ki:
    • yinelemede bir sonraki değeri döndürür
    • durumu bir sonraki değere işaret edecek şekilde günceller
    • StopIteration yükselterek yapıldığında sinyalleri
  • ve bu kendiliğinden tekrarlanabilir (self işlevini döndüren bir __iter__ yöntemine sahip olduğu anlamına gelir).

Notlar:

  • Python 3'teki __next__ yöntemi, Python 2'de yazılan next ve
  • Yerleşik işlevi next(), kendisine iletilen nesnede bu yöntemi çağırır.

Örneğin:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable
294

Yukarıdaki cevaplar harika, ama gördüğümlerin çoğunda olduğu gibi, benim gibi insanlar için ayrımyeter.

Ayrıca, insanlar daha önce "X, __foo__() yöntemine sahip bir nesnedir" gibi tanımlamalar yaparak "çok Pythonic" alma eğilimindedirler. Bu tür tanımlamalar doğrudur - bunlar ördek yazma felsefesine dayanır, ancak metotlara odaklanma, kavramı sadeliği ile anlamaya çalışırken ortaya çıkma eğilimindedir.

Bu yüzden versiyonumu ekliyorum.


Doğal dilde

  • yineleme , her seferinde bir öğeyi bir dizi öğede alma işlemidir.

Python'da

  • yinelenebilir , yinelemeli olan, basitçe söylemek gerekirse, yinelemede kullanılabileceği anlamına gelir; for döngüsüyle. Nasıl? yineleyicikullanarak. Aşağıda açıklayacağım.

  • ... while yineleyici gerçekten/yinelemenin nasıl yapılacağını tanımlayan bir nesnedir - özellikle sonrakieleman nedir? Bu yüzden next() yöntemine sahip olmalı.

Yineleyiciler kendileri de yinelenebilirler, __iter__() yönteminin, öğelerini next() işlevine önceki çağrılarda kullanıp kullanmadığına bakılmaksızın, aynı nesneyi (self) döndürür.


Peki Python yorumlayıcısı for x in obj: ifadesini gördüğünde ne düşünüyor?

Bak, for döngüsü. Bir yineleyici için bir işe benziyor ... Hadi bir tane alalım. ... Bu obj adamı var, hadi ona soralım.

"Mr. obj, yineleyiciniz var mı?" (... iter(obj) işlevini çağırır, bu da obj.__iter__() işlevini çağırır, bu da mutlu bir şekilde yeni bir yineleyici _i dağıtır.)

Tamam, bu kolaydı ... O zaman tekrarlamaya başlayalım. (x = _i.next() ... x = _i.next()...)

Bay obj bu testte başarılı olduğundan (belirli bir yineleyiciyi döndürerek belirli bir yöntemi uygulayarak), sıfatla ödüllendiririz: şimdi ona "yinelenebilir Bay obj" diyebilirsiniz.

Ancak, basit durumlarda, normal olarak yineleyiciden ve yinelenebilirden ayrı olarak yinelenmezsiniz. Bu yüzden sadece kendi/yineleyici olan birnesneyi tanımlarsınız. (Python, obj tarafından dağıtılan _i öğesinin o kadar da parlak olmamasıyla değil, sadece obj öğesinin kendisi olduğunu da umursamıyor.)

Bu yüzden gördüğüm çoğu örnekte (ve beni sürekli kafamda karıştıran şey), şunları görebiliyorsunuz:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

yerine

class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

Bununla birlikte, bir satır öğeye sahip olmak istediğinizde, ancak daha fazla "imleç" gibi yinelemenin yinelemeden ayrı tutulmasından faydalanabileceğiniz durumlar olabilir. Örneğin, "geçerli" ve "gelecek" öğelerle çalışmak istediğinizde, her ikisi için de ayrı yineleyicilere sahip olabilirsiniz. Veya çok büyük bir listeden çeken birden fazla iş parçacığı: her biri, tüm ögeler üzerinde dolaşmak için kendi yineleyicisine sahip olabilir. Bkz --- @ Raymond ve @ @ glglgl's yukarıdaki cevaplar.

Ne yapabileceğini düşün:

class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

Notlar:

  • Tekrar edeceğim: yineleyici yinelenemez. Yineleyici for döngüsünde "kaynak" olarak kullanılamaz. for döngüsünün öncelikle ihtiyaç duyduğu şey __iter__() (next() ile bir şey döndürür).

  • Tabii ki, for tek yineleme döngüsü değildir, bu yüzden yukarıdaki diğer bazı yapılar için de geçerlidir (while...).

  • Yineleyicinin next(), yinelemeyi durdurmak için StopIteration'ı atabilir. Buna rağmen, sonsuza dek yinelenebilir veya başka yollar kullanabilir.

  • Yukarıdaki "düşünce sürecinde", _i gerçekten mevcut değil. Bu ismi ben yaptım.

  • Python 3.x'te küçük bir değişiklik var: next() yöntemi (yerleşik değil) şimdi __next__() olarak adlandırılmalıdır. Evet, başından beri böyle olması gerekirdi.

  • Bunu da düşünebilirsiniz: yinelenebilir verilere sahip, yineleyici bir sonraki öğeyi çeker

Yasal Uyarı:Herhangi bir Python tercümanın geliştiricisi değilim, bu yüzden tercümanın "ne düşündüğünü" bilmiyorum. Yukarıdaki müzikleri sadece konuyu diğer açıklamalardan, deneylerden ve bir Python acemisinin gerçek yaşam deneyimlerinden nasıl anladığımı göstermekteyim.

92
Alois Mahdal

Yinelenebilir, __iter__() yöntemine sahip bir nesnedir. Muhtemelen list()s ve Tuple()s gibi birkaç defa yinelenebilir.

Bir yineleyici yinelenen nesnedir. __iter__() yöntemiyle döndürülür, kendi __iter__() yöntemiyle kendini döndürür ve next() yöntemine sahiptir (3.x'te __next__()).

Yineleme, bu next() resp adını verme işlemidir. __next__(), StopIteration 'yi yükseltir kadar.

Örnek:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1
21
glglgl

Kimseye yardım edip etmediğini bilmiyorum ama daima daha iyi anlamak için kafamdaki kavramları görselleştirmek istiyorum. Küçük bir oğlum olduğu için yinelenebilir/yineleyici konseptini tuğla ve beyaz kağıt ile görselleştiririm.

Farz edelim ki karanlık odadayız ve yerde oğlum için tuğlalar var. Farklı boyutta, renkli tuğlalar artık önemli değil. Bunun gibi 5 tane tuğla olduğunu varsayalım. Bu 5 tuğla nesne olarak tanımlanabilir - diyelim tuğla seti . Bu tuğla kitiyle birçok şey yapabiliriz - bir tanesini alıp sonra ikinciyi alabilir ve üçüncüsü, tuğlaların yerlerini değiştirebilir, ilkini ikincinin üstüne yerleştirebilir. Bunlarla bir sürü şey yapabiliriz. Bu nedenle, bu tuğla seti her tuğladan geçebileceğimiz ve onunla bir şeyler yapabileceğimiz gibi yinelenebilir nesne veya sıra 'dır. Bunu sadece küçük oğlum gibi yapabiliriz - bir brick bir seferde ile oynayabiliriz. Bu yüzden tekrar kendimi bu tuğla kitinin bir yinelenebilir olduğunu hayal ediyorum.

Şimdi, karanlık odada olduğumuzu hatırla. Ya da neredeyse karanlık. Mesele şu ki, bu tuğlaları net bir şekilde görmüyoruz, ne renk, ne şekil vb. Öyleyse onlarla bir şeyler yapmak istesek bile - aka içlerinde yineleyin - gerçekten değiliz ne olduğunu ve nasıl olduğunu biliyorum çünkü çok karanlık.

Yapabileceğimiz şey, ilk tuğlaya yakın - bir tuğla setinin elemanı olarak - ilk tuğla elemanının nerede olduğunu görmemiz için bir parça beyaz flüoresan kağıt koyabiliriz. Ve her bir kitten tuğla aldığımızda, karanlık odada görebilmek için beyaz kağıdın yerini sonraki tuğlaya değiştiriyoruz. Bu beyaz kağıt parçası yineleyici 'den başka bir şey değildir. Bu bir aynı zamanda nesne. Fakat yinelenebilir obje - tuğla setimizin elementleriyle çalışıp oynayabileceğimiz bir obje.

Bu arada, bir IDLE'de aşağıdakileri denediğimde ve bir TypeError aldığımda yaptığım ilk hatamı açıklıyor:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

Buradaki X listesi bizim tuğla kitimizdi ancak beyaz bir kağıt parçası değil. Önce bir yineleyici bulmam gerekiyordu:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

İşe yarayıp yaramadığını bilmiyorum, ama bana yardım etti. Birisi kavramın görselleştirilmesini onaylayabilir/düzeltebilirse minnettar olurum. Daha fazla bilgi edinmeme yardımcı olurdu.

9
Nikolay Dudaev

İşte benim hile sayfam:

 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+

Quiz: Görüyor musun ...

  • her yineleyici yinelenebilir mi?
  • bir konteyner nesnesinin __iter__() yöntemi bir jeneratör olarak uygulanabilir mi?
  • yinelenebilir bir artı bir __next__ yöntemi mutlaka bir yineleyici değil midir?
7
AXO

Bunu dokümantasyon 'dan çok daha kolay bulabileceğinizi sanmıyorum, ancak deneyeceğim:

  • Yinelenebilir , iterated üzerinde olabilir. Uygulamada genellikle a dizisi örn. başlangıcı ve sonu olan ve içindeki tüm öğeleri gözden geçirecek bir şey olan bir şey.
  • = 'De bir sonraki (veya ilk) öğeyi veren (veya tutan) yardımcı İteratör'ü yardımcı sözde yöntemi (veya sözde özniteliği) olarak düşünebilirsiniz. iterable . (Uygulamada, sadece next() yöntemini tanımlayan bir nesnedir)

  • Yineleme muhtemelen en iyi Merriam-Webster tarafından açıklanmıştır Kelimenin tanımı :

b: bir bilgisayar talimatı dizisinin belirli bir sayıda veya bir koşul yerine getirilinceye kadar tekrarlanması - özyinelemeyi karşılaştır

3
Kimvais

Yinelemeli: - yinelemeli bir şey yinelemelidir; Listeler, dizeler vb. gibi sekanslar gibi. Ayrıca, bir yineleyici döndüren __getItem__() yöntemine veya iter() işlevine sahiptir.

Iterator: - Yinelenebilir iter() yönteminden yineleyici nesnesini aldığımızda; elemanları birer birer elde etmek için __next__() yöntemini (python3'te) veya sadece next()'yi (python2'de) çağırırız. Bu sınıfa veya bu sınıfın örneğine yineleyici denir.

Dokümanlardan: -

Yineleyicilerin kullanımı Python'u bozar ve birleştirir. Sahnelerin arkasında, for ifadesi container nesnesindeki iter() işlevini çağırır. İşlev, kabın içindeki öğelere birer birer erişen __next__() yöntemini tanımlayan bir yineleyici nesnesi döndürür. Başka eleman olmadığında, __next__(), for döngüsünün sonlandırmasını söyleyen bir StopIteration istisnasını yükseltir. __next__() yerleşik işlevini kullanarak next() yöntemini çağırabilirsiniz; Bu örnek, hepsinin nasıl çalıştığını gösterir:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

Bir sınıfın dışı: -

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s
3
Vicrobot
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

yani,

  1. iterable, üzerinde ilmekli olabilen bir nesnedir . Örneğin. Liste, string, Tuple vb.

  2. iter nesnesindeki iterable işlevini kullanarak bir yineleyici nesnesi döndürür.

  3. şimdi bu iterator nesnesi 'in __next__ (Python 3'te veya Python 2'de sadece next) adında bir yöntemi vardır yinelenebilir öğelerin her birine erişir.

öyleyse, yukarıdaki kodun çıktısı:

1

2

3
arpan kumar

Iterables her seferinde yeni bir yineleyiciyi başlatan bir __iter__ yöntemine sahiptir.

Yineleyiciler, tek tek öğeleri döndüren bir __next__ yöntemini ve self değerini döndüren bir __iter__ yöntemini uygular.

Bu nedenle, yineleyiciler de yinelenebilir, ancak yineleyiciler yineleyiciler değildir.

Luciano Ramalho, Fluent Python.

1
trthhrtz

Yinelemelerle ve yinelemeciyle ilgilenmeden önce yinelemeli ve yinelemeciye karar veren ana faktör

Sıra: Sıra, veri toplanmasıdır.

Yinelemeli: Yinelemeli, Iter yöntemini destekleyen dizi türü nesnesidir.

İter yöntemi: iter yöntemi bir girdi olarak dizilim alır ve yineleyici olarak bilinen bir nesne oluşturur

Yineleyici: Yineleyici, sonraki yöntemi çağıran ve dizilimden geçen nesneydir. Bir sonraki yöntemi çağırırken, o anda dönüştürdüğü nesneyi döndürür.

örnek:

x=[1,2,3,4]

x veri toplanmasından oluşan bir sekanstır

y=iter(x)

İter (x) işlevini çağırırken, yalnızca x nesnesi iter yöntemine sahip olduğunda bir yineleyici döndürür, aksi halde bir istisna ortaya çıkar.

y=[1,2,3,4]

Y bir yineleyici olduğundan, next () metodunu destekler.

Bir sonraki yöntemi çağırırken listenin tek tek öğelerini tek tek döndürür.

Dizinin son elemanını döndürdükten sonra, bir sonraki yöntemi tekrar çağırırsak, bir StopIteration hatası verir.

örnek:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration
1
Shadow