Nic*_*mer 95 python select dictionary tuples key
假设我有大量不同颜色的水果,例如24个蓝色香蕉,12个青苹果,0个蓝色草莓等.我想用Python中的数据结构组织它们,以便于选择和排序.我的想法是将它们放入一个以元组为键的字典中,例如,
{ ('banana', 'blue' ): 24,
('apple', 'green'): 12,
('strawberry','blue' ): 0,
...
}
Run Code Online (Sandbox Code Playgroud)
甚至是字典,例如,
{ {'fruit': 'banana', 'color': 'blue' }: 24,
{'fruit': 'apple', 'color': 'green'}: 12,
{'fruit': 'strawberry','color': 'blue' }: 0,
...
}
Run Code Online (Sandbox Code Playgroud)
例如,我想检索所有蓝色水果或所有颜色的香蕉的列表,或者通过水果的名称对该字典进行排序.有没有办法以干净的方式做到这一点?
很可能是以元组为键的字典不是处理这种情况的正确方法.
欢迎所有建议!
sen*_*rle 139
就个人而言,我喜欢python的一个方面是元组 - 字典组合.你在这里实际上是一个二维数组(其中x =水果名称和y =颜色),我通常是实现二维数组的元组字典的支持者,至少当类似的东西numpy或数据库不合适时.简而言之,我认为你有一个很好的方法.
请注意,如果不做一些额外的工作,就不能将dicts用作dict中的键,因此这不是一个非常好的解决方案.
也就是说,您还应该考虑使用namedtuple().这样你就可以这样做:
>>> from collections import namedtuple
>>> Fruit = namedtuple("Fruit", ["name", "color"])
>>> f = Fruit(name="banana", color="red")
>>> print f
Fruit(name='banana', color='red')
>>> f.name
'banana'
>>> f.color
'red'
Run Code Online (Sandbox Code Playgroud)
现在你可以使用你的fruitcount dict:
>>> fruitcount = {Fruit("banana", "red"):5}
>>> fruitcount[f]
5
Run Code Online (Sandbox Code Playgroud)
其他技巧:
>>> fruits = fruitcount.keys()
>>> fruits.sort()
>>> print fruits
[Fruit(name='apple', color='green'),
Fruit(name='apple', color='red'),
Fruit(name='banana', color='blue'),
Fruit(name='strawberry', color='blue')]
>>> fruits.sort(key=lambda x:x.color)
>>> print fruits
[Fruit(name='banana', color='blue'),
Fruit(name='strawberry', color='blue'),
Fruit(name='apple', color='green'),
Fruit(name='apple', color='red')]
Run Code Online (Sandbox Code Playgroud)
回应chmullig,要获得一个水果的所有颜色的列表,你必须过滤键,即
bananas = [fruit for fruit in fruits if fruit.name=='banana']
Run Code Online (Sandbox Code Playgroud)
Cug*_*uga 18
您最好的选择是创建一个简单的数据结构来模拟您拥有的内容.然后,您可以将这些对象存储在一个简单的列表中,并按照您的意愿排序/检索它们.
对于这种情况,我将使用以下类:
class Fruit:
def __init__(self, name, color, quantity):
self.name = name
self.color = color
self.quantity = quantity
def __str__(self):
return "Name: %s, Color: %s, Quantity: %s" % \
(self.name, self.color, self.quantity)
Run Code Online (Sandbox Code Playgroud)
然后,您可以简单地构造"Fruit"实例并将它们添加到列表中,如下所示:
fruit1 = Fruit("apple", "red", 12)
fruit2 = Fruit("pear", "green", 22)
fruit3 = Fruit("banana", "yellow", 32)
fruits = [fruit3, fruit2, fruit1]
Run Code Online (Sandbox Code Playgroud)
简单的列表fruits将更容易,更容易混淆,维护得更好.
一些使用示例:
下面的所有输出都是在运行给定的代码片段后跟随的结果:
for fruit in fruits:
print fruit
Run Code Online (Sandbox Code Playgroud)
未排序列表:
显示:
Name: banana, Color: yellow, Quantity: 32
Name: pear, Color: green, Quantity: 22
Name: apple, Color: red, Quantity: 12
Run Code Online (Sandbox Code Playgroud)
按名称按字母顺序排序:
fruits.sort(key=lambda x: x.name.lower())
Run Code Online (Sandbox Code Playgroud)
显示:
Name: apple, Color: red, Quantity: 12
Name: banana, Color: yellow, Quantity: 32
Name: pear, Color: green, Quantity: 22
Run Code Online (Sandbox Code Playgroud)
按数量排序:
fruits.sort(key=lambda x: x.quantity)
Run Code Online (Sandbox Code Playgroud)
显示:
Name: apple, Color: red, Quantity: 12
Name: pear, Color: green, Quantity: 22
Name: banana, Color: yellow, Quantity: 32
Run Code Online (Sandbox Code Playgroud)
其中color == red:
red_fruit = filter(lambda f: f.color == "red", fruits)
Run Code Online (Sandbox Code Playgroud)
显示:
Name: apple, Color: red, Quantity: 12
Run Code Online (Sandbox Code Playgroud)
eyq*_*uem 17
数据库,词典的词典,词典列表的字典,名为元组(它是一个子类),sqlite,冗余...我不相信我的眼睛.还有什么 ?
"很可能是以元组为键的字典不是处理这种情况的正确方法."
"我的直觉是,数据库对OP的需求来说太过分了;"
是啊!我想
所以,在我看来,元组列表足够多了:
from operator import itemgetter
li = [ ('banana', 'blue' , 24) ,
('apple', 'green' , 12) ,
('strawberry', 'blue' , 16 ) ,
('banana', 'yellow' , 13) ,
('apple', 'gold' , 3 ) ,
('pear', 'yellow' , 10) ,
('strawberry', 'orange' , 27) ,
('apple', 'blue' , 21) ,
('apple', 'silver' , 0 ) ,
('strawberry', 'green' , 4 ) ,
('banana', 'brown' , 14) ,
('strawberry', 'yellow' , 31) ,
('apple', 'pink' , 9 ) ,
('strawberry', 'gold' , 0 ) ,
('pear', 'gold' , 66) ,
('apple', 'yellow' , 9 ) ,
('pear', 'brown' , 5 ) ,
('strawberry', 'pink' , 8 ) ,
('apple', 'purple' , 7 ) ,
('pear', 'blue' , 51) ,
('chesnut', 'yellow', 0 ) ]
print set( u[1] for u in li ),': all potential colors'
print set( c for f,c,n in li if n!=0),': all effective colors'
print [ c for f,c,n in li if f=='banana' ],': all potential colors of bananas'
print [ c for f,c,n in li if f=='banana' and n!=0],': all effective colors of bananas'
print
print set( u[0] for u in li ),': all potential fruits'
print set( f for f,c,n in li if n!=0),': all effective fruits'
print [ f for f,c,n in li if c=='yellow' ],': all potential fruits being yellow'
print [ f for f,c,n in li if c=='yellow' and n!=0],': all effective fruits being yellow'
print
print len(set( u[1] for u in li )),': number of all potential colors'
print len(set(c for f,c,n in li if n!=0)),': number of all effective colors'
print len( [c for f,c,n in li if f=='strawberry']),': number of potential colors of strawberry'
print len( [c for f,c,n in li if f=='strawberry' and n!=0]),': number of effective colors of strawberry'
print
# sorting li by name of fruit
print sorted(li),' sorted li by name of fruit'
print
# sorting li by number
print sorted(li, key = itemgetter(2)),' sorted li by number'
print
# sorting li first by name of color and secondly by name of fruit
print sorted(li, key = itemgetter(1,0)),' sorted li first by name of color and secondly by name of fruit'
print
Run Code Online (Sandbox Code Playgroud)
结果
set(['blue', 'brown', 'gold', 'purple', 'yellow', 'pink', 'green', 'orange', 'silver']) : all potential colors
set(['blue', 'brown', 'gold', 'purple', 'yellow', 'pink', 'green', 'orange']) : all effective colors
['blue', 'yellow', 'brown'] : all potential colors of bananas
['blue', 'yellow', 'brown'] : all effective colors of bananas
set(['strawberry', 'chesnut', 'pear', 'banana', 'apple']) : all potential fruits
set(['strawberry', 'pear', 'banana', 'apple']) : all effective fruits
['banana', 'pear', 'strawberry', 'apple', 'chesnut'] : all potential fruits being yellow
['banana', 'pear', 'strawberry', 'apple'] : all effective fruits being yellow
9 : number of all potential colors
8 : number of all effective colors
6 : number of potential colors of strawberry
5 : number of effective colors of strawberry
[('apple', 'blue', 21), ('apple', 'gold', 3), ('apple', 'green', 12), ('apple', 'pink', 9), ('apple', 'purple', 7), ('apple', 'silver', 0), ('apple', 'yellow', 9), ('banana', 'blue', 24), ('banana', 'brown', 14), ('banana', 'yellow', 13), ('chesnut', 'yellow', 0), ('pear', 'blue', 51), ('pear', 'brown', 5), ('pear', 'gold', 66), ('pear', 'yellow', 10), ('strawberry', 'blue', 16), ('strawberry', 'gold', 0), ('strawberry', 'green', 4), ('strawberry', 'orange', 27), ('strawberry', 'pink', 8), ('strawberry', 'yellow', 31)] sorted li by name of fruit
[('apple', 'silver', 0), ('strawberry', 'gold', 0), ('chesnut', 'yellow', 0), ('apple', 'gold', 3), ('strawberry', 'green', 4), ('pear', 'brown', 5), ('apple', 'purple', 7), ('strawberry', 'pink', 8), ('apple', 'pink', 9), ('apple', 'yellow', 9), ('pear', 'yellow', 10), ('apple', 'green', 12), ('banana', 'yellow', 13), ('banana', 'brown', 14), ('strawberry', 'blue', 16), ('apple', 'blue', 21), ('banana', 'blue', 24), ('strawberry', 'orange', 27), ('strawberry', 'yellow', 31), ('pear', 'blue', 51), ('pear', 'gold', 66)] sorted li by number
[('apple', 'blue', 21), ('banana', 'blue', 24), ('pear', 'blue', 51), ('strawberry', 'blue', 16), ('banana', 'brown', 14), ('pear', 'brown', 5), ('apple', 'gold', 3), ('pear', 'gold', 66), ('strawberry', 'gold', 0), ('apple', 'green', 12), ('strawberry', 'green', 4), ('strawberry', 'orange', 27), ('apple', 'pink', 9), ('strawberry', 'pink', 8), ('apple', 'purple', 7), ('apple', 'silver', 0), ('apple', 'yellow', 9), ('banana', 'yellow', 13), ('chesnut', 'yellow', 0), ('pear', 'yellow', 10), ('strawberry', 'yellow', 31)] sorted li first by name of color and secondly by name of fruit
Run Code Online (Sandbox Code Playgroud)
chm*_*lig 13
在这种情况下,字典可能不是您应该使用的字典.更全功能的图书馆将是更好的选择.可能是一个真正的数据库.最简单的是sqlite.您可以通过传入字符串':memory:'而不是文件名来将整个事物保存在内存中.
如果您确实希望继续沿着此路径继续,可以使用键或值中的额外属性来执行此操作.然而,字典不能成为另一个字典的关键,但元组可以.文档解释了什么是允许的.它必须是一个不可变对象,它包括仅包含字符串和数字的字符串,数字和元组(以及递归仅包含这些类型的更多元组...).
你可以用你的第一个例子d = {('apple', 'red') : 4},但要查询你想要的东西会非常困难.你需要做这样的事情:
#find all apples
apples = [d[key] for key in d.keys() if key[0] == 'apple']
#find all red items
red = [d[key] for key in d.keys() if key[1] == 'red']
#the red apple
redapples = d[('apple', 'red')]
Run Code Online (Sandbox Code Playgroud)