我正在寻找可能包含数字(整数或浮点数)的Python列表的第一个元素,或者包含相同数量的嵌套子列表的多个级别。在这些示例中,我们假设我一直在寻找数字' 1'。如果列表中没有包含子列表,我们有:
>>> foo = [1,2,3]
>>> foo[0]
1
如果列表包含一个子列表,并且我知道这些信息,我可以再次使用
获得1>>> foo = [[1,2],[3,4]]
>>> foo[0][0]
1
同样,如果我的列表的第一个元素是包含列表的列表:
>>> foo = [[[1,2],[3,4]],[[5,6],[7,8]]]
>>> foo[0][0][0]
1
是否有一般方法可以在foo
中获取第一个整数或浮点数,而不需要递归调用函数,直到向下钻取到不再是列表的foo[0]
值?
答案 0 :(得分:2)
对此的一般情况答案是"修复您的数据结构。"列表应该是同质的,例如列表中的每个元素都应具有相同的类型(int
或list of ints
或list of lists of ints
或等等。
这里的特殊情况是递归,直到找到一个数字并将其返回。
def foo(lst):
first_el = lst[0]
if isinstance(first_el, (float, int)):
return first_el
else:
return foo(first_el)
答案 1 :(得分:2)
不应该需要递归。假设您一直在使用list
和int
,那么这对您来说非常有效。
foo = [[[1,2],[3,4]],[[5,6],[7,8]]]
result = None
while True:
try:
result = foo[0]
except TypeError:
break
与其他答案不同,这要求宽恕而不是许可,这有点像Pythonic。
如果确实希望成为Pythonic,您可以定义如下函数。但是,根据您的规范,这肯定会有点过分。
def first_scalar(foo):
result = None
while True:
try:
result = next(iter(foo))
except TypeError:
return result
请注意,如果参数不是None
,则返回iterable
。这同样适用于第一段代码。
请注意,如果最深的“最左侧”子列表为空,则不起作用。为了解决此问题,您需要完全展平列表。
def _flatten(foo):
try:
for item in foo:
yield from flatten(foo)
except TypeError:
yield foo
def flatten(foo):
for item in foo:
yield from _flatten(foo)
def first_scalar(foo):
return next(flatten(foo))
请注意,上述内容必须至少用Python 3.3编写。
以下代码适用于早期版本的Python。
def _flatten(foo):
try:
for item in foo:
for subitem in _flatten(foo):
yield subitem
except TypeError:
yield foo
def flatten(foo):
for item in foo:
for subitem in _flatten(foo):
yield subitem
答案 2 :(得分:1)
创建一个简单的递归函数:
>>> def getFirst(l):
return l[0] if not isinstance(l[0],list) else getFirst(l[0])
>>> getFirst([1,2,3,4])
1
>>> getFirst([[1,2,3],[4,5]])
1
>>> getFirst([[[4,2],12,[1,3]],1])
4
如果l[0]
不是列表,则会返回l[0]
。否则,它将以递归方式返回l[0]
的第一项
答案 3 :(得分:1)
你可以“潜入”,没有任何递归:
<jdbc:outbound-endpoint queryKey="InsertRecords"connector-ref="DBConnector" doc:name="InsertRecords (Deprecated)"
exchange-pattern="request-response" queryTimeout="-1">
<jdbc:transaction action="NONE"></jdbc:transaction>
<jdbc:query key="InsertRecords" value="call InsertUserRecords('Test', 'Test')"></jdbc:query>
</jdbc:outbound-endpoint>
答案 4 :(得分:1)
如果确实想要避免任何循环或递归,则会出现丑陋变通方法。将列表转换为字符串,然后删除特定于列表的字符:
socketListenerThread
当然,只有列表由字符串或整数组成时才有效。如果列表中的对象是自定义的,则必须将它们转换为字符串。但是,由于存在未知数量的子列表,您必须使用递归,因此使用此解决方法是没有意义的。
另一件事,列表和子列表中的元素可能与列表特定的字符具有相同的字符,例如'['或',',因此这也是一个问题。
简而言之,这是一个糟糕的解决方法,只有在列表和子列表由数字组成时才有效。否则,最有必要使用某种递归。