我试图更深入地了解for
如何在Python中针对不同的数据类型循环。使用for循环对数组进行迭代的最简单方法是
for i in range(len(array)):
do_something(array[i])
我也知道我可以
for i in array:
do_something(i)
我想知道的是它的作用
for i, j in range(len(array)):
# What is i and j here?
或
for i, j in array:
# What is i and j in this case?
如果我尝试与dict
ionaries或tuples
使用相同的想法怎么办?
答案 0 :(得分:5)
最简单的方法是第二种方法,而不是第一种:
for i in array:
do_something(i)
从不执行此操作:
for i in range(len(array)):
do_something(array[i])
如果由于某种原因(通常不需要)而需要数组中的索引,请改为执行此操作:
for i, element in enumerate(array):
do_something(element)
这是一个错误:
for i, j in range(len(array)):
# What is i and j here?
您将得到TypeError: 'int' object is not iterable
尝试将一个整数分解为两个名称。
for i, j in array:
# What is i and j in this case?
假定数组为“二维”,例如:
>>> for i, j in [(0, 1), ('a', 'b')]:
... print('i:', i, 'j:', j)
...
i: 0 j: 1
i: a j: b
注意: ['these', 'structures']
在Python中称为列表,而不是数组。
答案 1 :(得分:2)
您的第三个循环将不起作用,因为它将为TypeError
而不是int
抛出iterable
。这是因为您试图将数组的索引“ unpack
”“ i
”和“ j
”索引“不可能”。打开包装的示例如下:
tup = (1,2)
a,b = tup
在其中您将a
分配为tuple
中的第一个值,并将b
分配为第二个值。当您可能有一个function
返回一个元组的值,并且您想在调用该函数时立即将其拆包时,这也很有用。喜欢,
train_X, train_Y, validate_X, validate_Y = make_data(data)
我相信您所指的更常见的循环情况是如何遍历数组项及其索引。
for i, e in enumerate(array):
...
和
for k,v in d.items():
...
遍历dictionary
中的项目时。此外,如果您有两个列表l1
和l2
,可以像这样
for e1, e2 in zip(l1,l2):
...
请注意,如果迭代时长度不相等,这将截断较长的列表。或者说,您有一个列表列表,其中外部列表的长度为m
,内部列表的长度为n
,并且您宁愿遍历按索引分组在一起的内部照明元素。这样可以有效地迭代矩阵的转置,您也可以使用zip执行此操作。
for inner_joined in zip(*matrix): # will run m times
# len(inner_joined) == m
...
答案 2 :(得分:1)
Python的for循环是基于迭代器的循环(这就是bruno desthuilliers说它“适用于所有可迭代对象(列表,元组,集合,字典,迭代器,生成器等)”的原因。字符串也是另一种常见的用法可迭代的类型。
假设您有一个元组列表。使用您共享的术语,可以同时遍历键和值。对于实例
tuple_list = [(1, "Countries, Cities and Villages"),(2,"Animals"),(3, "Objects")]
for k, v in tuple_list:
print(i, j)
您将获得输出
1 Countries, Cities and Villages
2 Animals
3 Objects
如果您使用字典,那么您也可以做到这一点。这里的区别是需要.items()
dictionary = {1: "Countries, Cities and Villages", 2: "Animals", 3: "Objects"}
for k, v in dictionary.items():
print(k, v)
dictionary和dictionary.items()之间的区别如下
dictionary: {1: 'Countries, Cities and Villages', 2: 'Animals', 3: 'Objects'}
dictionary.items(): dict_items([(1, 'Countries, Cities and Villages'), (2, 'Animals'), (3, 'Objects')])
使用dictionary.items(),我们将获得一个包含字典的键-值对的视图对象,作为列表中的元组。换句话说,使用dictionary.items(),您还将获得一个元组列表。如果您不使用它,将会得到
TypeError:无法解压缩不可迭代的int对象
如果要使用简单的列表获得相同的输出,则必须使用诸如enumerate()
list = ["Countries, Cities and Villages","Animals", "Objects"]
for k, v in enumerate(list, 1): # 1 means that I want to start from 1 instead of 0
print(k, v)
否则,您会得到
ValueError:太多值无法解包(预期2)
因此,这自然引发了一个问题... 我是否总是需要一个元组列表?否。使用enumerate()我们将获得一个枚举对象。
答案 3 :(得分:0)
实际上,第二个是“使用for循环对数组进行迭代的最简单方法”(Python类型称为“ list” BTW)。
for item in somelist:
do_something_with(item)
哪个FWIW适用于所有可迭代对象(列表,元组,集合,字典,迭代器,生成器等)。
基于范围的C样式版本被认为是高度Python风格的,并且仅适用于列表或类似列表的可迭代对象。
我想知道的是它的作用
for i, j in range(len(array)):
# What is i and j here?
好吧,您可以自己进行测试...但是结果很明显:它将解开TypeError
,因为解压缩仅适用于可迭代对象,而int不可迭代。
或
for i, j in array:
# What is i and j in this case?
取决于array
是什么以及在其上进行迭代时产生什么。如果它是2元组的列表或产生2元组的迭代器,则i
和j
将是当前迭代项的元素,即:
array = [(letter, ord(letter)) for letter in "abcdef"]
for letter, letter_ord in array:
print("{} : {}".format(letter, letter_ord))
否则,它很可能也会引发TypeError。
请注意,如果您想同时拥有项目和索引,则解决方案是内置的enumerate(sequence)
,它会为每个项目生成一个(index, item)
元组:
array = list("abcdef")
for index, letter in enumerate(array):
print("{} : {}".format(index, letter)
答案 4 :(得分:0)
我只是想补充一点,即使在Python中,您也可以只使用局部变量就可以使用经典的C样式循环获得for in
效果
l = len(mylist) #I often need to use this more than once anyways
for n in range(l-1):
i = mylist[n]
print("iterator:",n, " item:",i)