在Python中创建一个包含列表的字典

20

我有一个巨大的文件(有约200k个输入)。这些输入的形式如下:

A B C D
B E F
C A B D
D  

我正在阅读这个文件,并将其存储在一个列表中,方法如下:

text = f.read().split('\n')

这个代码根据换行符将文件分割成多个部分,因此文本如下所示:

[[A B C D] [B E F] [C A B D] [D]]

现在我需要把这些值存储到一个字典中,其中键值是每个列表的第一个元素。即键将是A、B、C、D。我发现很难将剩余元素作为值输入。也就是说,字典应该如下所示:

{A: [B C D]; B: [E F]; C: [A B D]; D: []}

我已经完成了以下操作:

    inlinkDict = {}
    for doc in text:
    adoc= doc.split(' ')
    docid = adoc[0]
    inlinkDict[docid] = inlinkDict.get(docid,0) +  {I do not understand what to put in here}
请帮忙解决如何向字典中添加值。如果列表中除了键值之外没有其他元素,则应为0。就像示例中的0一样。

您想要将字典设为{A: [B, C, D]; B: [E, F]; C: [A, B, D]; D: []}吗?或者是{A: "B C D"; B: "E F"; C: "A B D"; D: 0} - huon
请编辑您的问题,说明您希望如何处理重复键;例如,如果您有一个包含“A P Q R”的第5行,您想如何存储值B C D ... 作为列表['B'、'C'、'D']?如果是空列表的情况最好表示为空列表'[]'而不是整数'0'。 - John Machin
@JohnMachin:没有重复的值。是的,将值存储为列表肯定会有所帮助。我会编辑我的问题。 - gsb
3个回答

27
一个字典推导能够轻松完成这个任务:
>>> s = [['A','B','C','D'], ['B','E','F'], ['C','A','B','D'], ['D']]
>>> {t[0]:t[1:] for t in s}
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['E', 'F'], 'D': []}

1
如果您使用的是不支持字典推导式的旧版Python,您可以使用dict(t[0], t[1:] for t in s)代替。 - forivall
12
如果您使用的是早于生成器表达式的Python版本,您可以使用dict([(t[0], t[1:]) for t in s])。如果您使用的是更早的版本,您可以使用for t in s: d[t[0]] = t[1:]。如果您的环境连Python都不支持,您可以使用Dartmouth BASIC来DIM一个数组,以便编写自己的哈希函数模拟散列表。如果您在没有高级语言的系统上工作,您可以手动将汇编代码转换为机器语言,并使用切换开关输入程序... - Raymond Hettinger
哈哈哈。只是2.5和2.6仍然很常见,而字典推导式只在2.7中添加了。 - forivall

22

尝试使用切片:

inlinkDict[docid] = adoc[1:]

如果只有键值在行上,这将给你一个空列表而不是 0。要得到 0,请使用 or(它始终返回其中的一个操作数):

inlinkDict[docid] = adoc[1:] or 0

使用字典推导式更为简单:

>>> with open('/tmp/spam.txt') as f:
...     data = [line.split() for line in f]
... 
>>> {d[0]: d[1:] for d in data}
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['E', 'F'], 'D': []}
>>> {d[0]: ' '.join(d[1:]) if d[1:] else 0 for d in data}
{'A': 'B C D', 'C': 'A B D', 'B': 'E F', 'D': 0}

注意:字典的键必须是唯一的,因此,如果您有两个以“C”开头的行,则第一个行将被覆盖。


4

接受的答案是正确的,除了它会将整个文件读入内存(如果您有一个大文件,则可能不理想),并且它会覆盖重复的键。

另一种使用defaultdict的方法可解决这个问题,该方法可从Python 2.4中使用:

from collections import defaultdict
d = defaultdict(list)
with open('/tmp/spam.txt') as f:
  for line in f:
    parts = line.strip().split()
    d[parts[0]] += parts[1:]

输入:

A B C D
B E F
C A B D
D  
C H I J

结果:

>>> d = defaultdict(list)
>>> with open('/tmp/spam.txt') as f:
...    for line in f:
...      parts = line.strip().split()
...      d[parts[0]] += parts[1:]
...
>>> d['C']
['A', 'B', 'D', 'H', 'I', 'J']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接