简体   繁体   English

基于每个列表元素中的字符值迭代列表(python)

[英]iterating through list based on character value in each list element (python)

I have a list of values in the form of: [0,1], [0,2], [1,3], [2,4], [3,5], [4,6], [5,7], [7,9] .我有以下形式的值列表: [0,1], [0,2], [1,3], [2,4], [3,5], [4,6], [5,7], [7,9]

I would like to iterate through the list starting at [0,1] and if the second character (in this case, 1) is equal to that of the first character of another list element (in this case this would correspond to [1,3] , it would go to [1,3] and then [3,5], [5,7] and finally [7,9] . At which point it would start at the second element ([0,2]) and do the same thing, culminating in two lists.我想遍历从[0,1]开始的列表,如果第二个字符(在本例中为 1)等于另一个列表元素的第一个字符(在本例中这将对应于[1,3] ,它会去[1,3]然后是[3,5], [5,7]最后是[7,9] 。此时它将从第二个元素([0,2])并做同样的事情,最终形成两个列表。

To clarify, the list itself contains values that are both even and odd, unlike the example I show here, so I can't split it based on that.澄清一下,列表本身包含偶数和奇数的值,这与我在此处展示的示例不同,因此我无法基于此拆分它。

Any ideas to push me in the right direction with this would be greatly appreciated.任何将我推向正确方向的想法都将不胜感激。

Here is a recursive solution that attempts to follow the items for as long as possible, taking care of alternate unvisited paths too:这是一个递归解决方案,它尝试尽可能长时间地跟踪项目,同时也照顾备用的未访问路径:

from collections import defaultdict
def split(items):
    # create lookup
    lookup = defaultdict(set)
    for k, v in items:
        lookup[k].add(v)

    results = []
    while sum(map(len, lookup.values())):
        # get first element from remaining items
        first_k = min((k for k in lookup if len(lookup[k])))
        first = first_k, min(lookup[first_k])

        # follow that element
        results.append(follow(first, lookup))

    return results

def follow(item, lookup):
    item_k, item_v = item
    lookup[item_k].remove(item_v)

    result = [item]
    # loop through all follow-up items (if any)
    for next_item in sorted(lookup[item_v]):
        # recursively follow the follow-up item
        result.extend(follow((item_v, next_item), lookup))
    return result

Used lke this:像这样使用:

>>> def test(items):
        for x in split(items):
            print(x)

>>> test([[0,1], [0,2], [1,3], [2,4], [3,5], [4,6], [7,9]])
[(0, 1), (1, 3), (3, 5)]
[(0, 2), (2, 4), (4, 6)]
[(7, 9)]

It ignores paths to items that have already been visited:它忽略已经访问过的项目的路径:

>>> test([[0, 1], [1, 2], [4, 3], [2, 5], [5, 1]])
[(0, 1), (1, 2), (2, 5), (5, 1)]
[(4, 3)]

But follows all of them in order when there are multiple ones (sorted, not original order):但是当有多个(已排序,而不是原始顺序)时,请按顺序跟踪所有这些:

>>> test([[0, 1], [1, 2], [1, 3], [2, 4], [3, 5]])
[(0, 1), (1, 2), (2, 4), (1, 3), (3, 5)]

And it works for your complex example too:它也适用于您的复杂示例:

>>> test([[0, 1], [0, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7], [7, 9], [8, 10], [8, 11], [10, 12], [11, 13], [11, 14], [12, 15], [12, 16], [6, 8], [8, 17]])
[(0, 1), (1, 3), (3, 5), (5, 7), (7, 9)]
[(0, 2), (2, 4), (4, 6), (6, 8), (8, 10), (10, 12), (12, 15), (12, 16), (8, 11), (11, 13), (11, 14), (8, 17)]

You can't iterate through the usual way which is using the "for" loop, because for loop can't jump to a specific value.您无法通过使用“for”循环的通常方式进行迭代,因为 for 循环无法跳转到特定值。 So use a "while" loop.所以使用“while”循环。 This code finds all the value packs that matches their last and first values.此代码查找与其最后一个值和第一个值匹配的所有值包。 So you can use it for finding matching values from the middle of a complex list too.因此,您也可以使用它从复杂列表的中间查找匹配值。

listoflists = [[0,1], [0,2], [1,3], [2,4], [3,5], [4,6], [7,9]]

addr0 = 0
addr1 = 0
print len(listoflists)
while addr0 < len(listoflists):
    val0 = listoflists[addr0]
    last_num = val0[1]
    while addr1 < len(listoflists): # Second iteration for finding the matching value
        val1 = listoflists[addr1]
        if val1[0] == last_num:
            print "found: ",listoflists[addr0], listoflists[addr1] # Found the matching values
            addr0 = addr1
            break
        addr1 += 1
    addr0 += 1

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

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