这是一个非常简单的python机制问题。为什么我不能在范围original_list中代替i而不是在范围内的i(0,len(original_list))。人们通常使用的范围超过前者吗?谢谢!
# "If I give you an array with negative and positive numbers (i.e. {3,2,-3,6,4,-7}) and asked you to sort it so that the negative numbers appeared first but you didn't change the relative order of the remaining numbers, how would you do it? (i.e. the final result would be {-3,-7,3,2,6,4}).
original_list = [3, 2, -3, 6, 4, -7]
pos_list = []
neg_list = []
for i in range(0, len(original_list)):
if original_list[i] < 0:
neg_list.append(original_list[i])
else:
pos_list.append(original_list[i])
print neg_list + pos_list
答案 0 :(得分:7)
在您的情况下,由于您不需要使用列表中项目的索引,您可以使用for in
迭代它:
>>> for item in original_list:
... if item < 0:
... ...
如果要迭代列表中项目的索引,请使用for in range(..)
:
>>> for i in range(len(original_list)):
... if original_list[i] < 0:
... ...
或者,如果你需要循环体中的item和index,你可能还想使用enumerate()
:
>>> for i, item in enumerate(original_list):
... if item < 0:
... ...
通过这种方式,您还可以使用original_list[i]
。
答案 1 :(得分:5)
构造range(len(my_sequence))
通常不被认为是惯用的Python。它将您的代码集中在比我们通常尝试编写的更低级别的机制上,这使得它更难以阅读。因此,在这里使用range
主要被视为使用C语言等低级语言编码的人员。
例如,参见Raymond Hettinger的演讲Transforming Code into Beautiful Idiomatic Python - 他建议的第一件事就是将for i in range(len(sequence))
改为for item in sequence
。然后,他继续提及enumerate
和zip
,以涵盖您可能会想要恢复使用range
的情况。他还提到惯用的方法更快。除了Python内置类型(不出所料)优化以快速运行惯用构造之外,不难看出为什么这对于某些其他数据结构可能是正确的 - 例如,链接列表可以比随机访问具有更快的顺序,这意味着依赖于my_linked_list[i]
的循环可能变成二次时间运算而不是线性运算。
如果您在codereview.SE上点击[python]标记,您可以不时看到类似的建议。
答案 2 :(得分:1)
如果您打开翻译并执行以下操作:
help(range)
你会得到这个:
Help on built-in function range in module __builtin__:
range(...)
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
从描述中可以看出,这是范围的工作方式。它需要一个起始位置,然后是一个停止位置,然后是每次上升x的可选步骤。
修改的
要根据您的评论回答,您获得索引超出范围的原因是因为当您这样做时:
for i in arr:
print(arr[i])
这不起作用,因为for i in arr
会为您提供数组中每个项目的值。那么,你正在做的事情实际上是将值放入arr,就好像它是索引一样。但事实并非如此。
执行此操作时:
for i in range(0, len(arr))
这里发生的是您获得的增量值基于数组的大小,因此您可以将该值用作列表的索引。
答案 3 :(得分:1)
不要使用范围迭代值列表。做for item in list
。如果你需要索引使用枚举。
for index, value in enumerate(original_list):
print index
print value
或者
for item in original_list:
if item < 0:
neg_list.append(item)
else:
pos_list.append(item)
您可能正在使用for item in original_list:
获取异常,因为您尝试执行neg_list.append(original_list[item])
,这可能会导致类似original_list[-3]
或original_list[6]
的内容超出范围
答案 4 :(得分:1)
lst=[1,2,3,4]
for i in range(lst):
print lst[i]
你不能这样做。这是因为:
TypeError:range()整数结束参数expected,got list。
你能做的是:
for i in range(len(lst)): #i is the index here
print lst[i]
输出: 1 2 3 4
或者,
for i in lst: #i is the value here
print i
输出:
1
2
3
4
实际上,range
不是惯用的python。你可以避免它。如果您需要索引,可以使用enumerate
,如下所示:
for i,j in enumerate(lst): #i is the index and j is the value here
print i,j
希望你现在很清楚。
答案 5 :(得分:0)
itertools
documentation中有一个分区方法:
def partition(pred, iterable):
'Use a predicate to partition entries into false entries and true entries'
# partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9
t1, t2 = tee(iterable)
return filterfalse(pred, t1), filter(pred, t2)
您可以像以下一样使用它:
positives, negatives = partition(lambda value: value < 0, originals)
答案 6 :(得分:0)
我真的不知道为什么没有人写关于列表元素占用的信息。当您使用简单的...
If departmentHead(n) = "Name1" Then
.Cells(14, 7).Value = "VIO"
.Cells(31, 7).Value = "VIO"
.Cells(31, 4).Value = departmentHead(n)
ElseIf departmentHead(n) = "Name2" Then
.Cells(14, 7).Value = "ITO"
.Cells(31, 7).Value = "ITO"
.Cells(31, 4).Value = departmentHead(n)
ElseIf departmentHead(n) = "Name3" Then
.Cells(14, 7).Value = "VSKO"
.Cells(31, 7).Value = "VSKO"
.Cells(31, 4).Value = departmentHead(n)
...
Else
.Cells(14, 7).Value = ""
.Cells(31, 7).Value = ""
.Cells(31, 4).Value = ""
End If
并尝试在list元素中写入一些信息时-不起作用。仅当使用元素的索引时,例如for element in list
,您才能重写它。