if<\/A><\/><\SPAN>. La expresión combinada genera valores para una función envolvente:<\/>\n<SPAN class=\"operator token\">>><\/>\n<SPAN class=\"operator token\">><\/> sum<SPAN class=\"punctuation token\">(<\/>i<SPAN class=\"operator token\">*<\/>i <SPAN class=\"keyword token\">for<\/> i <SPAN class=\"keyword token\">in<\/> range<SPAN class=\"punctuation token\">(<\/>10<SPAN class=\"punctuation token\">)<\/><SPAn class=\"punctuation token\">)<\/> <SPAN class=\"comment token\"># suma de cuadrados 0, 1, 4, ... 81<\/>\n285<\/> courier new,courier;"><A href="https://docs.python.org/2/library/functions.html#iter" rel="nofollow noopener noreferrer" target="_blank">iter()</A></SPAN> función o úsala en un bucle <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/reference/compound_stmts.html#for" rel="nofollow noopener noreferrer" target="_blank">for</A></SPAN>. Intentar esto con un iterador solo devolverá el mismo objeto iterador agotado usado en la pasada de iteración anterior, haciendo que parezca un contenedor vacío.</P><P></P><P><STRONG>secuencia</STRONG></P><P style="margin-left: 30px;">Un <A href="https://docs.python.org/2/glossary.html#term-iterable" rel="nofollow noopener noreferrer" target="_blank"><EM>iterable</EM> </A>que soporta acceso eficiente a elementos usando índices enteros mediante el método especial <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/reference/datamodel.html#object.__getitem__" rel="nofollow noopener noreferrer" target="_blank">__getitem__()</A></SPAN> y define un método <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/library/functions.html#len" rel="nofollow noopener noreferrer" target="_blank">len()</A></SPAN> que devuelve la longitud de la secuencia. Algunos tipos de secuencia incorporados son <A href="https://docs.python.org/2/library/functions.html#list" rel="nofollow noopener noreferrer" target="_blank"><SPAN style="font-family: courier new,courier;">list</SPAN></A>, <A href="https://docs.python.org/2/library/functions.html#str" rel="nofollow noopener noreferrer" target="_blank"><SPAN style="font-family: courier new,courier;">str</SPAN></A>, <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/library/functions.html#tuple" rel="nofollow noopener noreferrer" target="_blank">tuple</A></SPAN>, y <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/library/functions.html#unicode" rel="nofollow noopener noreferrer" target="_blank">unicode</A></SPAN>. Nota que <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/library/stdtypes.html#dict" rel="nofollow noopener noreferrer" target="_blank">dict</A></SPAN> también soporta <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/reference/datamodel.html#object.__getitem__" rel="nofollow noopener noreferrer" target="_blank">__getitem__()</A></SPAN> y <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/reference/datamodel.html#object.__len__" rel="nofollow noopener noreferrer" target="_blank">__len__()</A></SPAN>, pero se considera un mapeo más que una secuencia porque las búsquedas usan claves arbitrarias <A href="https://docs.python.org/2/glossary.html#term-immutable" rel="nofollow noopener noreferrer" target="_blank"><EM>immutable</EM> </A>en lugar de enteros.</P><P>Comparado con el antiguo glosario de <A href="http://resources.arcgis.com/" rel="nofollow noopener noreferrer" target="_blank">ArcGIS Resources</A>, ahora renombrado <A href="http://support.esri.com/en/knowledgebase/Gisdictionary/browse" rel="nofollow noopener noreferrer" target="_blank">GIS Dictionary </A>y alojado en <A href="http://support.esri.com/" rel="nofollow noopener noreferrer" target="_blank">Esri Support</A>, el <A href="https://docs.python.org/2/glossary.html" rel="nofollow noopener noreferrer" target="_blank">Python Glossary </A>es bastante sustancial. Dicho esto, el Python Glossary también es uno de esos que tiene sentido para personas que ya conocen la respuesta, pero puede ser un poco difícil para quienes son nuevos en el lenguaje.</P><P></P><P>Al revisar el extracto del glosario arriba, se puede deducir que algunos métodos especiales/mágicos/dunder son muy importantes para la iteración: <SPAN style="font-family: courier new,courier;">__iter__()</SPAN>, <SPAN style="font-family: courier new,courier;">__getitem__()</SPAN>, y <SPAN style="font-family: courier new,courier;">next()</SPAN> (<EM>o <SPAN style="font-family: courier new,courier;">__next__()</SPAN> si se trabaja en Python 3.x</EM>). También hay un par de funciones incorporadas importantes que interactúan con esos métodos: <SPAN style="font-family: courier new,courier;">iter()</SPAN> y <SPAN style="font-family: courier new,courier;">next()</SPAN>. Y por último, pero no menos importante, el bucle <SPAN style="font-family: courier new,courier;">for</SPAN> y la sentencia <SPAN style="font-family: courier new,courier;">yield</SPAN>. Hay más métodos, funciones, sentencias y estructuras de control involucradas con la iteración, pero los mencionados son centrales para cualquier discusión. Para aquellos lectores interesados en aprender más sobre iteradores, generadores, secuencias, etc...; hay numerosos manuales y tutoriales que ya han sido escritos y están a solo una búsqueda rápida en Google.</P><P></P><P>Las listas son tan comunes en Python, y los recién llegados al lenguaje las conocen tan temprano, que usaré ejemplos de listas de Python para contexto junto con los ejemplos del cursor de búsqueda ArcPy Data Access. El Python Glossary indica que una lista es "una secuencia incorporada de Python," y una secuencia es "un iterable que soporta acceso eficiente a elementos usando índices enteros...." La documentación del ArcPy <A href="https://pro.arcgis.com/en/pro-app/arcpy/data-access/searchcursor-class.htm" rel="nofollow noopener noreferrer" target="_blank">Data Access SearchCursor </A>indica que el cursor de búsqueda "devuelve un iterador de tuplas." Dado que los iteradores también son iterables, se tiene la sensación de que las funciones incorporadas y expresiones comúnmente usadas para manipular listas también pueden usarse con los cursores ArcPy.</P><P></P><P style="padding-left: 30px;"><EM>Aunque uno puede usar la función incorporada <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/library/functions.html#dir" rel="nofollow noopener noreferrer" target="_blank">dir()</A></SPAN> para intentar devolver una lista de atributos válidos para un objeto, voy a evitar inspeccionar los objetos de esa manera porque introduciría desorden por todos los atributos que no están relacionados con la iteración. En cambio, confiaré en la función incorporada <SPAN style="font-family: courier new,courier;"><A href="https://docs.python.org/2/library/functions.html#isinstance" rel="nofollow noopener noreferrer" target="_blank">isinstance()</A></SPAN> junto con las clases base abstractas (ABCs) incorporadas para observar rasgos de iteración.</EM></P><P></P><PRE class="lia-code-sample line-numbers language-none"><CODE><SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> <SPAN class="comment token">#importar ABCs relevantes del módulo collections</SPAN>
<span class='operator token'>>></span><span class='operator token'>></span> from collections import Iterable, Iterator, Sequence
<span class='operator token'>>></span><span class='operator token'>></span>
<span class='operator token'>>></span><span class='operator token'>></span> <span class='comment token'>#crear una lista de ejemplo y arcpy.da.SearchCursor</span>
<span class='operator token'>>></span><span class='operator token'>></span> l = [10, 20, 30, 40, 50]
<span class='operator token'>>></span><span class='operator token'>></span> cur = arcpy.da.SearchCursor(fc,["OID@", "SHAPE@"])
<span class='operator token'>>></span><span class='operator token'>></span>
<span class='operator token'>>></span><span class='operator token'>></span> <span class='comment token'>#observar rasgos de iteración de objetos de ejemplo</span>
<span class='operator token'>>></span><span class='operator token'>></span> abcs = (Iterable, Iterator, Sequence)
<span class='operator token'>>></span><span class='operator token'>></span> [isinstance(l, abc) for abc in abcs]
[True, False, True] <span class='comment token'>#Iterable, no Iterator, Sequence</span>
<span class='operator token'>>></span><span class='operator token'>></span>
<span class='operator token'>>></span><span class='operator token'>></span> <SPAN class="punctuation token">[</SPAN>isinstance<SPAN class="punctuation token">(</SPAN>cur<SPAN class="punctuation token">,</SPAN> abc<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">para</SPAN> abc <SPAN class="keyword token">en</SPAN> abcs<SPAN class="punctuation token">]</SPAN>
<SPAN class="punctuation token">[</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="token boolean">False</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="comment token">#Iterable, Iterator, no Sequence</SPAN>
<SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN>
<SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> <SPAN class="comment token">#mirar los tipos para objetos de muestra e iteradores de objetos de muestra</SPAN>
<SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> it_l <SPAN class="operator token">=</SPAN> iter<SPAN class="punctuation token">(</SPAN>l<SPAN class="punctuation token">)</SPAN>
<SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> type<SPAN class="punctuation token">(</SPAN>l<SPAN class="punctuation token">)</SPAN>
<SPAN class="operator token"><</SPAN>type <SPAN class="string token">'list'</SPAN><SPAN class="operator token">></SPAN>
<SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> type<SPAN class="punctuation token">(</SPAN>it_l<SPAN class="punctuation token">)</SPAN>
<SPAN class="operator token"><</SPAN>type <SPAN class="string token">'listiterator'</SPAN><SPAN class="operator token">></SPAN>
<SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN>
<SPAN class="operator token">>></span><span class="operator token">></span> it_cur <span class="operator token">=</span> iter<span class="punctuation token">(</span>cur<span class="punctuation token">)</span>
<span class="operator token">>></span><span class="operator token">></span> type<span class="punctuation token">(</span>cur<span class="punctuation token">)</span>
<span class="operator token"><</span>type <span class="string token">'da.SearchCursor'</span><span class="operator token">></span>
<span class="operator token">>></span><span class="operator token">></span> type<span class="punctuation token">(</span>it_cur<span class="punctuation token">)</span>
<span class="operator token"><</span>type <span class="string token">'da.SearchCursor'</span><span class="operator token">></span>
<span class="operator token">>></span><span class="operator token">></span>
<span class="operator token">>></span><span class="operator token">></span> <span class="comment token">#mirar la identidad de los objetos cursor</span>
<span class="operator token">>></span><span class="operator token">></span> id<span class="punctuation token">(</span>cur<span class="punctuation token">)</span>
<span class="number token">262686224</span>
<span class="operator token">>></span><span class="operator token">></span> id<span class="punctuation token">(</span>it_cur<span class="punctuation token">)</span>
<span class="number token">262686224</span>
<span class="operator token">>></span><span class="operator token"></span>
<span class='line-numbers-rows'><span><<EMOJI_0>></span><span><<EMOJI_1>></span><span><<EMOJI_2>></span><span><<EMOJI_3>></span><span><<EMOJI_4>></span><span><<EMOJI_5>></span><span><<EMOJI_6>></span><span><<EMOJI_7>></span><span><<EMOJI_8>></span><span><<EMOJI_9>></span><span><<EMOJI_10>></span><span><<EMOJI_11>></span><span><<EMOJI_12>></span><span><<EMOJI_13>></span><span><<EMOJI_14>></span><span><<EMOJI_15>></span><span><<EMOJI_16>></span><span><<EMOJI_17>></span><span><<EMOJI_18>></span><span><<EMOJI_19>></span><span><<EMOJI_20>></span><span><<EMOJI_21>></span><span><<EMOJI_22>></ span >< span >& lt ; & lt ; EM OJ I _ 23 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 24 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 25 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 26 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 27 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 28 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 29 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 30 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 31 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 32 & gt ; & gt ; </ span >< span >& lt ; & lt ; EM OJ I _ 33 & gt ; & gt ; </ span ></ span >
Como se puede ver arriba, lo que básicamente demuestra lo que se indica en el Glosario de Python, una lista es tanto un iterable como una secuencia pero no un iterador mientras que un cursor de búsqueda de ArcPy Data Access es tanto un iterable como un iterador pero no una secuencia. De las líneas 20-21, vemos que llamar a iter()< /Span > en una lista devuelve un nuevo tipo de objeto así como un nuevo objeto, es decir, el listiterator< /Span>. De las líneas 26-27, vemos que llamar a iter()< /Span > en un cursor de búsqueda devuelve un cursor de búsqueda en lugar de un nuevo objeto iterador. No solo se devuelve un cursor de búsqueda al llamar a iter()< /Span>, sino que las líneas 30-33 muestran que se devuelve el mismo objeto cursor de búsqueda al hacerlo. Este patrón de diseño de tener un iterable que sea su propio iterador es bastante común en Python.
En la próxima publicación de esta serie, avanzaremos más allá de los componentes de la iteración y comenzaremos a iterar realmente sobre objetos Python, incluidos los cursores ArcPy Data Access.