【问题标题】:Python - Nested ListsPython - 嵌套列表
【发布时间】:2015-06-08 21:26:06
【问题描述】:

我正在尝试交叉检查两个嵌套列表值,如果找到匹配项,请将 list1 中的值附加到 list2 中。

例如;

list1 = [[ip, hostname], [ip, hostname], [ip, hostname]]
list2 = [[ip, ip_upper, type, hostname, location], [ip, ip_upper, type, hostname, location], [ip, ip_upper, type, hostname, location]]

我想检查list1[x][0]中的值是否在list2中,如果是,请将List2[x][3]的值替换为List1[x][1]

我正在尝试的是;

count = 0;
for row in list2:
    if row[0] in hosts[count][0]:
        new_hostname = hosts[count][1]
        row[4].append(new_hostname)
        count += 1
    else:
         continue
         count += 1

我知道上面是不正确的,我正在努力弄清楚如何在遍历 list2 时访问值 list1。原因是因为我需要检查每一行,然后用行的值再修改行内的具体值。

感谢您的快速响应!

我尝试实现给定的代码,但在尝试从我的列表中创建字典时遇到了麻烦:

哇,你们!

    def doStuff(list1, list2):
        mydic = dict(list2)
        for l in list1:
            l[3] = mydic.get(l[0], l[3])
        return mydic

new_dic = doStuff(hostname, old_rows) 

我收到错误消息;

    mydic = dict(list2)
ValueError: dictionary update sequence element #0 has length 6; 2 is required

有什么想法吗?

【问题讨论】:

  • 您有什么具体问题吗?如果是这样,请编辑您的帖子并包含您的问题。
  • 可以list2改订单吗?
  • 仅供参考,但如果 list 中的元素在质量上是异质的,那么它可能不应该是 list
  • 列表的顺序并不重要,只需要检查每个IP并将值插入为nesc即可。
  • 我的原始答案需要一个 2 元素列表的列表,你的似乎以某种方式交换了,也许参数也应该交换?

标签: python list nested iteration


【解决方案1】:

我猜这很好用,它的时间复杂度只有 O(n + m),其中 n 和 m 是每个列表的长度。

def doStuff(list1, list2):
    mydic = dict(list1)
    for l in list2:
        l[3] = mydic.get(l[0], l[3])

【讨论】:

  • 我会避免在 mydic 中进行双重查找,而是使用变量。即使它是一个小的mydic... ;)
  • 点了,我希望 mydic 足够大,值得麻烦,但是..但是我应该如何在不必捕获异常的情况下做到这一点?我觉得这不是一个正确的方法......
  • 查看顶部以获得响应。
【解决方案2】:

假设 ip 字段值支持相等比较 (==),此解决方案可能会对您有所帮助。它很简单,很蹩脚,可能不是很优化,但它确实有效。

注意:它适用于 list2 中 list1 的每个元素的每次出现,因此如果您在 list2 中有多个匹配项,它们都会被更新。

list1 = [['1.2.3.4', 'ciao.com'],
         ['1.2.3.5', 'prova.net'],
         ['1.2.2.2', 'uovo.net']]
list2 = [['1.2.3.4', '1.2.3.x', 'type', 'xyz.com', 'puglia'],
         ['1.2.3.7', '1.2.3.x', 'type', 'zyx.com', 'lazio'],
         ['1.2.3.5', '1.2.3.x', 'type', 'yxz.com', 'molise']]

print list1
print list2

for i in list1:
    ip = i[0]
    for j in list2:
        cur_ip = j[0]
        if ip == cur_ip:
            j[3] = i[1]

print list2

输出:

[['1.2.3.4', 'ciao.com'], ['1.2.3.5', 'prova.net'], ['1.2.2.2', 'uovo.net']]
[['1.2.3.4', '1.2.3.x', 'type', 'xyz.com', 'puglia'], ['1.2.3.7', '1.2.3.x', 'type', 'zyx.com', 'lazio'], ['1.2.3.5', '1.2.3.x', 'type', 'yxz.com', 'molise']]
[['1.2.3.4', '1.2.3.x', 'type', 'ciao.com', 'puglia'], ['1.2.3.7', '1.2.3.x', 'type', 'zyx.com', 'lazio'], ['1.2.3.5', '1.2.3.x', 'type', 'prova.net', 'molise']]

【讨论】:

  • 正是我想要的。我严重过度复杂化并感到困惑。谢谢。
  • 这很容易理解,但是如果两个列表都足够大,它可能会慢得多。
  • 埃米利亚诺是正确的。如果您没有任何多次出现要替换,请使用字典。
  • 同意,谢谢。我很简单地从两个 csv 读取并输出到一个新的 csv,并且只有几百个 ips 需要检查。它也只会做一次,所以不需要花哨
【解决方案3】:

ip 上的目标列表进行排序,然后使用itertools.groupby 迭代目标。如果list2 中有很多项不需要修改(它们被跳过),它可能会有一点优势。

import operator, itertools
ip = operator.itemgetter(0)
keys = dict(list1)
list2.sort(key = ip)
for key, group in itertools.groupby(list2, ip):
    if key in keys:
        for item in group:
            item[3] = keys[key]

【讨论】:

    猜你喜欢
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    相关资源
    最近更新 更多