简体   繁体   English

遍历Python列表,保留嵌入式列表的结构

[英]Iterate over Python list, preserving structure of embedded lists

Python newbie here. Python新手在这里。 I'm trying to perform a basic function on a list containing lists of various lengths. 我正在尝试在包含各种长度列表的列表上执行基本功能。 Within these lists are tuples containing pairs of elements that I intend to use as ranges. 这些列表中的元组包含我打算用作范围的成对元素。 I want to convert these elements into integers, and then create a new tuple with the integers, followed by 2 , which will represent the iterator. 我想将这些元素转换成整数,然后用整数创建一个新的元组,然后是2 ,它将代表迭代器。

I want l : 我想l

l = [[('100', '200'), ('300', '400'), ('500', '600')], [('100', '200')], [('100', '200')]]

To be replaced by l_upd l_upd代替

l_upd = [[(100, 200, 2), (300, 400, 2), (500, 600, 2)], [(100, 200, 2)], [(100, 200, 2)]]

This obviously doesn't work (and I couldn't figure out how to get the 2 placed as an element: 这显然行不通(而且我不知道如何将2作为元素放置:

l1 = []
l2 = []

for pairs in l:
    for pair in pairs:
        l1.append(int(i[0]))
        l2.append(int(i[1]))

l_upd = zip(l1, l2)

EDIT: I would prefer to not use a list comprehension method, because I need to include an if , else statement. 编辑:我宁愿不使用列表推导方法,因为我需要包括一个ifelse语句。 Some of the elements contain letters, and some are empty. 有些元素包含字母,有些则为空。

Something like the following is needed for these exceptions: 这些异常需要以下内容:

for pair in pairs:
    if pair[0].isdigit():
        addr_from.append(int(i[0]))
    elif pair[0].isalnum() is True and pair[0].isdigit is False:
        addr_from.append(re.sub(r'((?:[A-Z].*?)?(?:\d.*?)?[A-Z]+)(\d+)',r'\1%\2',pair[0]))
    else:
        addr_from.append(pair[0])
    if pair[1].isdigit():
        addr_to.append(int(i[1]) + 2)
    elif pair[1].isalnum() is True and pair[1].isdigit is False:
        addr_to.append(re.sub(r'((?:[A-Z].*?)?(?:\d.*?)?[A-Z]+)(\d+)',r'\1%\2',pair[1]))

you could write some recursive function to do the job(which means the function can deal with any level of nested lists unless it hits maximum recursion depth) 您可以编写一些递归函数来完成这项工作(这意味着该函数可以处理任何级别的嵌套列表,除非达到最大递归深度)

def addtwo(lst):
   new_lst = []
   for item in lst:
     if isinstance(item, list):
       new_lst.append(addtwo(item))
     elif isinstance(item, tuple):
       new_lst.append(item + (2,))

   return new_lst

l = [[('100', '200'), ('300', '400'), ('500', '600')], [('100', '200')], [('100', '200')]]
print addtwo(l)

#[[('100', '200', 2), ('300', '400', 2), ('500', '600', 2)], [('100', '200', 2)], [('100', '200', 2)]]

Using list comprehensions: 使用列表推导:

>>> [[tuple(map(int, pair)) + (2,) for pair in pairs] for pairs in l]
[[(100, 200, 2), (300, 400, 2), (500, 600, 2)], [(100, 200, 2)], [(100, 200, 2)]]

Or without the map: 还是没有地图:

>>> [[(int(a), int(b), 2) for a, b in pairs] for pairs in l]
[[(100, 200, 2), (300, 400, 2), (500, 600, 2)], [(100, 200, 2)], [(100, 200, 2)]]

Edit 编辑

Even with further checks, you can still use list comprehension. 即使进行了进一步的检查,您仍然可以使用列表理解。 I assume that the if/else section you have added to your question should be applied to every pair, and the resulting tuple would be (addr_from, addr_to, 2) then, right? 我假设您添加到问题中的if / else部分应该应用于每对,结果元组应该是(addr_from, addr_to, 2) ,对吧?

def processPair(a, b):
    if a.isdigit():
        a = int(a)
    elif a.isalnum():
        a = re.sub(r'((?:[A-Z].*?)?(?:\d.*?)?[A-Z]+)(\d+)', r'\1%\2', a)
    if b.isdigit():
        b = int(b) + 2
    elif b.isalnum():
        b = re.sub(r'((?:[A-Z].*?)?(?:\d.*?)?[A-Z]+)(\d+)', r'\1%\2', b)
    return (a, b, 2)

Here I have defined a function that processes the tuple (a, b) as you did in your question. 在这里,我定义了一个函数,可以像在问题中一样处理元组(a, b) Note that I have changed it to just modify the values of the variables and return a finished tuple (with the added 2) instead of appending it to some global list. 请注意,我已经对其进行了更改,仅修改变量的值并返回一个完成的元组(添加了2),而不是将其附加到某些全局列表中。

I have also simplified it a bit. 我也简化了一点。 a.isdigit() is True is the same as a.isdigit() as that already returns a boolean value. a.isdigit() is Truea.isdigit()相同,因为它已经返回了布尔值。 Same for a.isdigit() == False , which is the same as not a.isdigit() . a.isdigit() == False相同,与not a.isdigit()相同。 In that situation you can also remove redundant checks. 在这种情况下,您也可以删除多余的支票。 After checking a.isdigit() on the if , you do not need to check its opposite on the elif ; 检查后a.isdigit()if ,你不需要去检查它的反面elif ; it is guaranteed to be false, as you have already checked it before. 由于您之前已经检查过,因此保证它为假。

That being said, when you have said function, you can then use list comprehensions again, to get your output. 话虽这么说,当您说完函数时,然后可以再次使用列表推导来获取输出。 Of course with your example l , this is a bit boring: 当然,对于您的示例l ,这有点无聊:

>>> [[processPair(*pair) for pair in pairs] for pairs in l]
[[(100, 202, 2), (300, 402, 2), (500, 602, 2)], [(100, 202, 2)], [(100, 202, 2)]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM