两段Python代码之间的差异
我正在做如下练习:两段Python代码之间的差异,python,list,Python,List,我正在做如下练习: # B. front_x # Given a list of strings, return a list with the strings # in sorted order, except group all the strings that begin with 'x' first. # e.g. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] yields # ['xanadu', 'xyz', 'aardvark', 'a
# B. front_x
# Given a list of strings, return a list with the strings
# in sorted order, except group all the strings that begin with 'x' first.
# e.g. ['mix', 'xyz', 'apple', 'xanadu', 'aardvark'] yields
# ['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
# Hint: this can be done by making 2 lists and sorting each of them
# before combining them.
样品溶液:
def front_x(words):
listX = []
listO = []
for w in words:
if w.startswith('x'):
listX.append(w)
else:
listO.append(w)
listX.sort()
listO.sort()
return listX + listO
def front_x(words):
listX = []
for w in words:
if w.startswith('x'):
listX.append(w)
words.remove(w)
listX.sort()
words.sort()
return listX + words
我的解决方案:
def front_x(words):
listX = []
listO = []
for w in words:
if w.startswith('x'):
listX.append(w)
else:
listO.append(w)
listX.sort()
listO.sort()
return listX + listO
def front_x(words):
listX = []
for w in words:
if w.startswith('x'):
listX.append(w)
words.remove(w)
listX.sort()
words.sort()
return listX + words
当我测试我的解决方案时,结果有点奇怪。以下是我的解决方案的源代码:。您可能想尝试一下。更改正在迭代的列表会导致未定义的行为。这就是为什么示例解决方案创建两个新列表,而不是从源列表中删除
for w in words:
if w.startswith('x'):
listX.append(w)
words.remove(w) # Problem here!
有关此问题的讨论,请参阅。它基本上归结为列表迭代器遍历列表的索引,而不返回并检查修改(这将是昂贵的!)
如果希望避免创建第二个列表,则必须执行两次迭代。一个用于迭代
单词
以创建列表x
,另一个用于迭代列表x
从单词中删除。问题是您循环列表并从中删除元素(修改它):
例如:
>>> a = range(5)
>>> for i in a:
... a.remove(i)
...
>>> a
[1, 3]
该代码的工作原理如下:
- 获取第一个元素,然后将其删除
- 移动到下一个元素。但是它不再是
1
,因为我们以前删除了0
,因此1
成为新的第一个元素。因此,下一个元素是2
,跳过1
- 与
3
和4
相同
两个主要区别:
在Python中,从循环中的列表中删除元素(列表在循环中被迭代)并不十分有效。如果您使用的是Java,则会出现一个异常,表明您正在修改正在迭代的集合。Python显然没有喊出这个错误@费利克斯·克林在他的回答中解释得很好
此外,您正在修改输入参数words
。因此,函数front_x
的调用者将在函数执行后看到单词
被修改。除非明确预期,否则最好避免这种行为。假设您的程序正在使用单词
执行其他操作。在示例解决方案中保留两个列表是更好的方法
该提示具有误导性且不必要,您可以在不单独排序和组合两个列表的情况下执行此操作:
>>> items = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
>>> sorted(items, key=lambda item: (item[0]!='x', item))
['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
内置的sorted()函数接受一个option键参数,该参数告诉它按什么排序。在本例中,您希望为原始列表中的每个元素创建一个元组,如(False,'xanadu')或(True,'apple'),这可以通过lambda来实现。除了“我的代码怎么了?”-1:“结果有点奇怪”之外,您还有什么特别的问题吗。含糊不清,难以回答。请提供一些你想解决的具体问题。是的,我明白了。在您的示例中,从中删除0后,1将成为第0个元素,并将在下一个循环中跳过。