27

我有一个如下所示的数据列表:

// timestep,x_position,y_position
0,4,7
0,2,7
0,9,5
0,6,7
1,2,5
1,4,7
1,9,0
1,6,8

...我想让它看起来像:

0, (4,7), (2,7), (9,5), (6,7)
1, (2,5), (4,7), (9,0), (6.8)

我的计划是使用字典,其中 t 的值是字典的键,而键的值将是一个列表。然后我可以将每个 (x,y) 附加到列表中。就像是:

# where t = 0, c = (4,7), d = {}

# code 1
d[t].append(c)

现在这会导致 IDLE 失败。但是,如果我这样做:

# code 2
d[t] = []
d[t].append(c)

...这行得通。

所以问题是:为什么代码 2 有效,但代码 1 无效?

PS 对我计划做的任何改进都会引起极大的兴趣!我想我必须通过输入检查每个循环上的字典,看看字典键是否已经存在,我猜是通过使用类似 max(d.keys()): 如果它存在,附加数据,如果不创建空列表作为字典值,然后在下一个循环中追加数据。

4

4 回答 4

72

让我们看看

d[t].append(c)

的价值是d[t]多少?尝试一下。

d = {}
t = 0
d[t]

你得到了什么?哦。里面没有任何东西dt.

现在试试这个。

d[t] = []
d[t]

啊。现在有一些东西dt.

您可以做几件事。

  1. 使用示例 2。
  2. 使用setdefault. d.setdefault(t,[]).append(c).
  3. 使用collections.defaultdict。您将使用 adefaultdict(list)而不是简单的字典,{}.

编辑1.优化

给定来自上述形式的文件的输入行:ts、x、y,分组过程是不必要的。没有理由从 (ts, x, y) 的简单列表转到更复杂的 (ts, (x,y), (x,y), (x,y), ... ) 列表。原始列表可以在到达时完全处理。

d= collections.defaultdict(list)
for ts, x, y in someFileOrListOrQueryOrWhatever:
    d[ts].append( (x,y) )

编辑 2. 回答问题

“初始化字典时,你需要告诉字典键值数据结构是什么样的吗?”

我不确定这个问题是什么意思。由于所有字典都是键值结构,因此问题不是很清楚。因此,我将回顾这三个备选方案,这可能会回答这个问题。

示例 2

初始化

d= {}

采用

if t not in d:
    d[t] = list()
d[t].append( c )

每个字典值都必须初始化为一些有用的结构。在这种情况下,我们检查密钥是否存在;当密钥丢失时,我们创建密钥并分配一个空列表。

默认设置

初始化

d= {}

采用

d.setdefault(t,list()).append( c )

在这种情况下,我们利用该setdefault方法获取与键关联的值或创建与缺失键关联的新值。

默认字典

初始化

import collections
d = collections.defaultdict(list)

采用

d[t].append( c )

使用defaultdict初始化函数来丢失键。在这种情况下,我们提供了一个list函数,以便为缺少的键创建一个新的空列表。

于 2008-11-29T13:46:42.053 回答
12

我想你想使用 setdefault。使用起来有点奇怪,但正是你需要的。

d.setdefault(t, []).append(c)

如果该键存在,该.setdefault方法将返回绑定到字典键的元素(在我们的例子中是一个列表) 。t如果没有,它会将一个空列表绑定到该键t并返回它。因此,无论哪种方式,都会有一个列表,.append然后该方法可以将元组附加到该列表c

于 2008-11-29T14:28:09.927 回答
1
dict=[]  //it's not a dict, it's a list, the dictionary is dict={}
elem=[1,2,3]
dict.append(elem)

您可以通过这种方式访问​​单个元素:

print dict[0] // 0 is the index

输出将是:

[1, 2, 3]
于 2008-11-29T13:53:34.007 回答
1

如果您的数据尚未按所需标准排序,以下代码可能有助于对数据进行分组:

#!/usr/bin/env python
"""
$ cat data_shuffled.txt
0,2,7
1,4,7
0,4,7
1,9,0
1,2,5
0,6,7
1,6,8
0,9,5
"""
from itertools   import groupby
from operator    import itemgetter

# load the data and make sure it is sorted by the first column
sortby_key = itemgetter(0)
data = sorted((map(int, line.split(',')) for line in open('data_shuffled.txt')),
              key=sortby_key)

# group by the first column
grouped_data = []
for key, group in groupby(data, key=sortby_key):
    assert key == len(grouped_data) # assume the first column is 0,1, ...
    grouped_data.append([trio[1:] for trio in group])

# print the data
for i, pairs in enumerate(grouped_data):
    print i, pairs

输出:

0 [[2, 7], [4, 7], [6, 7], [9, 5]]
1 [[4, 7], [9, 0], [2, 5], [6, 8]]
于 2008-12-01T22:54:25.863 回答