Python 如何确定二维列表是否为;“矩形”;
现在,我正试图让我的程序将二维列表作为输入,并根据它是否为“矩形”(例如,[2,3]、[1,5]、[6,9]]为矩形,[2,3]、[1,8,6]]为非矩形)返回true或false。到目前为止,我已经得出以下结论:Python 如何确定二维列表是否为;“矩形”;,python,list,Python,List,现在,我正试图让我的程序将二维列表作为输入,并根据它是否为“矩形”(例如,[2,3]、[1,5]、[6,9]]为矩形,[2,3]、[1,8,6]]为非矩形)返回true或false。到目前为止,我已经得出以下结论: def rectangular(List): n = List for i in n: if len(i) != len(n[0]): return False elif len(i) == len(n[0]):
def rectangular(List):
n = List
for i in n:
if len(i) != len(n[0]):
return False
elif len(i) == len(n[0]):
i
我似乎不知道如何创建一个“真实”的案例。使用上面的elif,我可以循环浏览列表,但如果我要添加一个return true部分,它会在这种情况下立即停止。在这种情况下,while循环会更好吗?感谢您的帮助!谢谢。尝试将该功能与发电机一起使用:
def rectangular(lst):
first_len = len(lst[0])
# I used lst[1:] to skip the 0th element
return all(len(x) == first_len for x in lst[1:])
如果iterable的所有元素都是True
,则all
函数返回True
,否则返回False
很好,您没有调用变量list
,但大写的名称通常表示Python中的类,因此lst
比list
更好
注意:我假设“矩形”表示每个子列表的长度相同。如果实际上每个子列表应该(比如)有2个元素长,只需将
首先替换为2
文本,并在lst[1://code>上删除[1://code>。如果只传递一个元素的列表,您可能还需要添加一些异常处理。您可以确保列表中所有元素的长度都相同。或者在Python中:
all(map(lambda m: len(m) == len(x[0]), x))
其中x
是您要检查的内容
此解决方案的唯一问题是,如果列表看起来像[[1,2],[1[1,2],'ab']
,它仍然会返回True
。因此,您还需要进行一些类型检查 如果你到了最后没有发现一个错误的案例,那么你知道这是真的,对吗?没有其他的可能性
因此,您可以完全删除elif
,只需在末尾添加一个return True
:
def rectangular(List):
n = List
for i in n:
if len(i) != len(n[0]):
return False
return True
作为旁注,您的elif
与if
具有完全相反的条件,它最好像else:
那样编写。这样,你就不可能把相反的情况弄错,也不需要你的读者去发现它是相反的,等等
另外,没有理由将参数设为List
,然后将相同的值绑定到n
并使用它。为什么不首先采取n
def rectangular(n):
for i in n:
if len(i) != len(n[0]):
return False
return True
通过使用生成器表达式和all
函数替换for
语句,您可以使这一点更加简洁,甚至更具Python风格:
def rectangular(n):
return all(len(i) == len(n[0]) for i in n)
但实际上,这和你已经拥有的并没有太大区别。您应该了解它是如何工作的,但是如果您还不理解它,那么以更详细的方式进行操作是没有问题的
如果你想变得聪明:
def rectangular(n):
lengths = {len(i) for i in n}
return len(lengths) == 1
我们正在制作一套所有长度的。集合没有重复项,因此这是所有不同长度的集合。如果只有一个不同的长度,这意味着所有的长度都是相同的
但是,请注意,对于空列表,这将返回False
(因为有0个长度,而不是1),而其他两个将返回True
(因为如果没有要测试的值,则所有值的条件都为空)。我不确定你想要哪一个,但要想知道如何改变你选择的哪一个相对容易。二维列表矩形的定义不清楚。但是,就编程本身而言,在循环之前将标志设置为True,并检查所有可能使其在循环内不是矩形的条件。如果确定为非矩形,则将标志设置为False和break。在循环结束时,返回标志。为什么在此处使用map
而不是理解?没有理由。两者都很好,而且大部分是可交换的。从语义上说,当然,唯一的区别是这会稍微慢一些……但就可读性而言,表达式比包装在lambda中的表达式更容易理解。如果整个表达式只是一个函数调用,循环变量是唯一的参数,理解的可读性可能较低,想想映射(int,spam)
和(int(x)表示spam中的x)
。我认为这是Guido在添加理解后不反对map
和filter
的部分原因。