2011-12-29 80 views
1

例如,Python的字典或替代

if dict['sample']: 
    //append values to dict['sample'] 
else: 
    // assign new key to the python dictionary 

如果字典[ '样品']是空的,Python会引发错误。有谁知道一个更好的方法来检查这个?我想要的是类似的东西,我会有数据列表,比如说a,a,b,c,g,g,g,g,g。

所以,我想要python字典追加两个a,a到dict ['a']和g,g,g,g到dict ['g']的值,剩下的就像字典['b']等等.for循环将被执行以循环通过a,a,b,c,g,g,g,g,g的数据。

我希望我已经明确了我的问题。任何想法?最好,如果Python的字典有办法检查现有的密钥。

编辑

幸得@保罗麦圭尔。基于@Paul McGuire的回答,我已经想出了我想要的确切解决方案。如下图所示:

from collections import defaultdict 

class Test: 
    def __init__(self, a,b): 
     self.a=a 
     self.b=b 

data = [] 
data.append(Test(a=4,b=6)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=1,b=3)) 
data.append(Test(a=2,b=2)) 
data.append(Test(a=3,b=2)) 
data.append(Test(a=4,b=5)) 
data.append(Test(a=4,b=2)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=5,b=9)) 
data.append(Test(a=4,b=7)) 

dd = defaultdict(list) 
for c in data: 
    dd[c.a].append(c.b) 
print dd 
+0

另一个学习的机会 - * namedtuple *。替换你的Test类(它应该扩展'object',BTW),用下面的代码:'Test = namedtuple(“Test”,“ab”)',将'namedtuple'加入你从汇集模块导入的内容, 。 'namedtuples'对于这些简单的类结构类很方便,并且它们是不可变的,因此可以用作适当的字典键和设置值。 – PaulMcG 2011-12-30 16:39:41

+0

再次感谢您的知识。以上只是我写的一个例子。我应该从服务器端获取数据并返回GQL查询对象。但是你的建议肯定有助于未来的需求。再次感谢 ! :) – MrCooL 2011-12-30 18:37:13

回答

13

“如果键入字典”或“dict.get”或“字典”的旧方法。setdefault”都应该赞成现在的标准defaultdict的被搁置:

data = "aabcggggg" 

from collections import defaultdict 
dd = defaultdict(list) 
for c in data: 
    dd[c].append(c) 
print dd 

defaultdict需要重点生存的检查你的关心,你的所有代码所要做的就是1)定义了一个工厂函数或类用于初始化新密钥条目(在本例中为defaultdict(list))的defaultdict,以及2)定义如何处理每个密钥(dd[c].append(c))。实际上使用itertools.groupby,因为字母组对于每个分组值都是连续的。groupby返回元组的迭代器,每个元组都包含一个元组包含当前键值和匹配值的迭代器。以下代码通过将每个元组的列表值迭代器转换为实际列表(在list(v)中)并将键值列表元素的序列传递给字典构造函数来工作。

from itertools import groupby 
print dict((k,list(v)) for k,v in groupby(data)) 

打印:

{'a': ['a', 'a'], 'c': ['c'], 'b': ['b'], 'g': ['g', 'g', 'g', 'g', 'g']} 
+0

非常感谢@Paul McGuire,我没有详细描述我正在写的代码。我将其归纳为上面的问题。实际上,我将循环使用对象而不仅仅是字母。 但是,您的答案仍然为许多人提供额外的知识。非常感谢!非常感谢 ! ;) – MrCooL 2011-12-29 14:11:37

+0

顺便说一句@Paul McGuire,我只是想知道你和'if key in dict'之间有什么重大区别?因为对于我的情况,一旦检测到相同的密钥,我需要执行不同的操作。 如果这对更好的性能有影响,我想接受您的答案。但是,我只是想知道它是否解决了我的问题。我编辑了我的问题。 – MrCooL 2011-12-30 07:46:20

+0

Hi @Paul McGuire,我已经接受你的答案,因为我发布了最适合我要解决的问题的最新解决方案。 我已经在我的问题上发布了确切的解决方案。 :) 但是,我仍然希望你能解释你与他人之间有点显著差异,你已经从你的第一个声明“强调的老办法:‘如果在字典键’或‘dict.get’或“字典。 setdefault”都应该抛开赞成现在的标准defaultdict” – MrCooL 2011-12-30 08:20:31

2

每个dict键都应该包含一个列表。我对吗?

d = dict() 
try: 
    d['sample'].append(new_data) 
except KeyError: 
    d['sample'] = [new_data] 

我相信这会奏效。顺便说一句,你不应该使用dictonary的名字字典。字典已被用作函数。

编辑1:

我不太确定我明白你想要做什么。我也不知道我的解决方案是否是最好的解决方案。但是你试图这样做吗?这似乎有点奇怪?或者你想要统计每个字母出现多少次?

# Create a list named l. 
l = ['a', 'a', 'b', 'c', 'g', 'g', 'g', 'g','g'] 

# Create dictionary named d. 
d = dict() 

for i in l: 
    try: 
     d[i].append(i) 
    except KeyError: 
     d[i] = [i] 
+0

没关系。我想我错过了你的问题。 – 2011-12-29 11:47:57

+0

@Niclas Nilsson虽然没有直接解决我的问题,但它帮助我找出了除KeyError之外的解决方案:它帮助了很多@Niclas Nilsson:。我明显忽略了这一点。非常感谢 ! – MrCooL 2011-12-29 13:22:56

5
my_dict = {} 
my_dict.setdefault('sample', []).append(value) 

“setdefault”方法的第二个参数说的话应该是初始值,如果给定的键不存在

4

如果我理解你的价值观是列表。

if 'sample' in mydict: 
    pass #whatever 
else: 
    mydict['sample'] = [] 

你想要做的是以下几点:

A = ['a','a','b','b','b','c','c','c'] 

myDict = {} 
for i in A: 
    if i not in myDict: 
     myDict[i] = [] 
    myDict[i].append(i) 
print myDict 
+0

这也适用。我已经发布了我自己的答案,关于我认为我想要的最简单的解决方案。但是,决定把功劳归功于你,因为它的工作方式也很好。谢谢 ! – MrCooL 2011-12-29 13:30:21

+0

我明白为什么人们投了我的答案:即使是一个新手(像我一样)通过阅读我简单的代码来理解发生了什么。但是,在阅读这个问题的其他答案时,我了解到了defaultdict!事实上,如果我明白了,它就像字典的子类一样,我已经重载了成员函数来获取一个试图获取项目的项目(除了默认值)。 如果您仅将字典用作列表字典(并且这是您在整个程序中期望的行为),我的解决方案是无意义的(因为它需要大量的代码复制粘贴),并且解决方案是defaultdict! – jimifiki 2011-12-29 13:44:27

+0

我确实相信一个“如果”的陈述更美观,然后使用例外,就像我只是出于习惯。只是想告诉:) – 2011-12-29 13:52:23

0

如果您使用的是一些很老的Python:

if not myDict.has_key(key): 
    myDict[key]=[val] 
else: 
    myDict[key].append(val) 

最近对象的has_key一直赞成key in dict 弃用所以现在,它应该是:

if not key in myDict: 
    myDict[key]=[val] 
else: 
    myDict[key].append(val) 
+0

不要延续这种做法! has_key在许多版本之前被弃用,主张“if key in myDict:”。最近有没有 – PaulMcG 2011-12-29 11:52:27

+0

?可能没有太多人使用Python 2.1或更高版本 – 2011-12-29 13:41:06

+0

同意,但在我的防守中,OP从未提及过哪个版本的python。 – 2011-12-29 18:22:12

0

信贷应该去@Niclas尼尔森尽管他发布的解决方案并没有真正工作了我想要的东西,但是它没有帮我找出了解决方案,我想要最简单的形式。

不过,我很感谢大家在这里获得的额外知识和解决办法。非常感谢。

继实现我在最简单的方法想无需额外的库中导入等:

r = {} 

try: 
    if r['new_data']: 
     r['new_data'] = 'appending' 
except KeyError: 
    r['new_data'] = 'new value' 

print r['new_data'] 
+0

高兴它为你工作... – 2011-12-29 13:23:02

+0

再次感谢猪头非常感谢您的帮助保持良好的工作;。!) – MrCooL 2011-12-29 13:34:19

0

确切的解决方案,我想最如下图所示。信贷去@Paul McGuire

from collections import defaultdict 

class Test: 
    def __init__(self, a,b): 
     self.a=a 
     self.b=b 

data = [] 
data.append(Test(a=4,b=6)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=1,b=3)) 
data.append(Test(a=2,b=2)) 
data.append(Test(a=3,b=2)) 
data.append(Test(a=4,b=5)) 
data.append(Test(a=4,b=2)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=5,b=9)) 
data.append(Test(a=4,b=7)) 

dd = defaultdict(list) 
for c in data: 
    dd[c.a].append(c.b) 
print dd