Python 为什么我的代码不适用于单个列表,而适用于嵌套列表?
当有多个列表传入函数时,第一个打印系统工作。但是,当只传入一个列表时,会出现错误“AttributeError:‘int’对象没有属性‘pop’” 此代码试图从列表中删除一个项目,以查看该弹出项目是否仍存在于剩余列表中Python 为什么我的代码不适用于单个列表,而适用于嵌套列表?,python,list,nested-lists,Python,List,Nested Lists,当有多个列表传入函数时,第一个打印系统工作。但是,当只传入一个列表时,会出现错误“AttributeError:‘int’对象没有属性‘pop’” 此代码试图从列表中删除一个项目,以查看该弹出项目是否仍存在于剩余列表中 def check_row(p): for e in p: while e: x = e.pop() if x in e: return False return Tr
def check_row(p):
for e in p:
while e:
x = e.pop()
if x in e:
return False
return True
print check_row([[8,2,3,4,5],
[2,3,1,5,6],
[4,0,2,3,1]])
print check_row([1,2,3,4,5])
非常感谢。对于单个(非嵌套)列表,您正在对元素(
e
)调用.pop()
,这些元素不是列表,因此可能没有.pop
方法。对于单个(非嵌套)列表,您正在对元素(e
)调用.pop()
它们不是列表,因此可能没有.pop
方法。这是因为e
是列表的一个元素。在嵌套的列表中,e
是一个列表,而在第二个列表中,e
是一个整数。因此,e.pop
对第二个无效
您必须使其始终嵌套:
>>> print(check_row([[1, 2, 3, 4, 5]]))
True
这样,传递给check_行的值始终是一个嵌套列表,即使它只有一个元素
但至于检查元素是否仍在其他列表中,我将首先展平列表,然后检查列表中是否有重复的元素
import collections
def flatten(l):
for el in l:
if isinstance(el, collections.Iterable) and not isinstance(el, str):
for sub in flatten(el):
yield sub
else:
yield el
def check_row(p):
flat = list(flatten(p))
return len(flat) == len(set(flat))
这样,check_row
将始终生成您想要的结果,忽略它是列表或嵌套列表的事实:)
希望这有帮助 那是因为
e
是您列表中的一个元素。在嵌套的列表中,e
是一个列表,而在第二个列表中,e
是一个整数。因此,e.pop
对第二个无效
您必须使其始终嵌套:
>>> print(check_row([[1, 2, 3, 4, 5]]))
True
这样,传递给check_行的值始终是一个嵌套列表,即使它只有一个元素
但至于检查元素是否仍在其他列表中,我将首先展平列表,然后检查列表中是否有重复的元素
import collections
def flatten(l):
for el in l:
if isinstance(el, collections.Iterable) and not isinstance(el, str):
for sub in flatten(el):
yield sub
else:
yield el
def check_row(p):
flat = list(flatten(p))
return len(flat) == len(set(flat))
这样,check_row
将始终生成您想要的结果,忽略它是列表或嵌套列表的事实:)
希望这有帮助 您正在从元素而不是外部列表弹出项目。如果您的元素不是列表,那么不要试图将它们视为列表 但是,当在外部列表上循环时,不能从外部列表中删除项目,并期望循环不会跳转项目 如果要查看某项是否在列表中出现多次,请比较列表的
set()
的长度:
def check_row(row):
return len(row) == len(set(row))
这只适用于可散列值,嵌套列表不是,但至少不会像代码那样改变列表
您仍然可以使用列表扫描,但至少可以使用list.index()
将搜索限制为超出当前位置的开始索引:
def check_row(row):
for i, elem in enumerate(row):
try:
row.index(elem, i + 1)
return False # dupe found
except ValueError:
pass # no dupe found
return True
但是,这假设您只想测试外部列表中的重复项。在同一代码中支持嵌套结构和平面结构,而不详细说明每种情况下会发生什么,这要复杂得多。您是从元素中弹出项,而不是从外部列表中弹出项。如果您的元素不是列表,那么不要试图将它们视为列表 但是,当在外部列表上循环时,不能从外部列表中删除项目,并期望循环不会跳转项目 如果要查看某项是否在列表中出现多次,请比较列表的
set()
的长度:
def check_row(row):
return len(row) == len(set(row))
这只适用于可散列值,嵌套列表不是,但至少不会像代码那样改变列表
您仍然可以使用列表扫描,但至少可以使用list.index()
将搜索限制为超出当前位置的开始索引:
def check_row(row):
for i, elem in enumerate(row):
try:
row.index(elem, i + 1)
return False # dupe found
except ValueError:
pass # no dupe found
return True
但是,这假设您只想测试外部列表中的重复项。在同一代码中支持嵌套结构和平面结构,而不详细说明每种情况下会发生什么,这要复杂得多。您对自己的命名感到困惑。您调用的函数
check\u row
实际上会检查一个行列表,不管名称如何,因此将其传递给一行失败。事实上,你使用的是毫无意义的一个字母的名字也没有帮助。让我们更清楚地重写它:
如果需要检查单行的函数
def check_rows(rows):
for row in rows:
while row:
element = row.pop()
if element in row:
return False
return True
现在,它失败的原因应该更清楚了:您正在将一个行
作为行
传递给它,因此for row in rows
将获取元素而不是行,并且从那里开始,一切都会走下坡路
您可能需要的是一个在单行上工作的
check_row
函数,然后是一个在每行上调用check_row
的check_row
:
def check_row(row):
while row:
element = row.pop()
if element in row:
return False
return True
def check_rows(rows):
for row in rows:
if not check_row(row):
return False
return True
但我真的不知道你为什么想要这个函数。它破坏性地修改行,删除每个元素直到第一个副本。你为什么要那样?例如,Martijn Pieters的解决方案更简单、更高效,并且具有非破坏性:
def check_row(row):
return len(set(row)) == len(row)
同时,让我们使用all
函数,而不是check\u rows
的显式循环:
def check_rows(rows):
return all(check_row(row) for row in rows)
你把自己和你的名字搞混了。您调用的函数
check\u row
实际上会检查一个行列表,不管名称如何,因此将其传递给一行失败。事实上,你使用的是毫无意义的一个字母的名字也没有帮助。让我们更清楚地重写它:
如果需要检查单行的函数
def check_rows(rows):
for row in rows:
while row:
element = row.pop()
if element in row:
return False
return True
现在,它失败的原因应该更清楚了:您正在将一个行
作为行
传递给它,因此for row in rows
将获取元素而不是行,并且从那里开始,一切都会走下坡路
您可能需要的是一个在单行上工作的
check\u row
函数,然后是一个