URN Logo
UNIX Resources » Linux » China Linux Forum » Python 编 程 » 19 » [精华] Python 食谱--1.6:在字典里把每一个键同多个值关联起来
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
[精华] Python 食谱--1.6:在字典里把每一个键同多个值关联起来
Author: rings    Posted: 2004-04-25 17:03    Length: 7,832 byte(s)
[Original] [Print] [Top]
1.6 Associating Multiple Values with Each Key in a Dictionary
在字典里把每一个键同多个值关联起来

Credit: Michael Chermside
1.6.1 Problem
问题

You need a dictionary that maps each key to multiple values.
你需要一个映射每个键到多个值的字典。

1.6.2 Solution
解决
By nature, a dictionary is a one-to-one mapping, but it's not hard to make it one-to-many梚n other words, to make one key map to multiple values. There are two possible approaches, depending on how you want to treat duplications in the set of values for a key. The following approach allows such duplications:
默认地,一个字典是一对一的映射。但是一对多也不是很困难,让一个键映射多个值就可以了:

d1 = {}
d1.setdefault(key, []).append(value)

while this approach automatically eliminates duplications:
这个方法自动地除去重复的项。

d2 = {}
d2.setdefault(key, {})[value] = 1

1.6.3 Discussion
讨论
A normal dictionary performs a simple mapping of a key to a value. This recipe shows two easy, efficient ways to achieve a mapping of each key to multiple values. The semantics of the two approaches differ slightly but importantly in how they deal with duplication. Each approach relies on the setdefault method of a dictionary to initialize the entry for a key in the dictionary, if needed, and in any case to return said entry.
一个正常的字典执行一个简单的一个键对应一个值的映射。这个配方显示两种简单,有效的方法让一个键对应多个值。两种方法的语义稍微有点不同。但是重要的是他们怎样处理重复的项。每个方法依赖于字典的setdefault方法去为一个键初始化入口。并且,如果需要,无论如何都会返回上述的入口。

Of course, you need to be able to do more than just add values for a key. With the first approach, which allows duplications, here's how to retrieve the list of values for a key:
当然,你需要能够做的比仅仅为一个键增加一个值更多。 对于第一种方法,它允许有重复的键,这儿是怎样为一个键去获取值的列表:
list_of_values = d1[key]

Here's how to remove one value for a key, if you don't mind leaving empty lists as items of d1 when the last value for a key is removed:
这是怎样为一个键移除一个值,如果你不关心一个键的最后的值被移走时,留下的空列表作为d2的元素:
d1[key].remove(value)

Despite the empty lists, it's still easy to test for the existence of a key with at least one value:
不管空列表,它仍然很容易去测试至少有一个值的键的存在:
def has_key_with_some_values(d, key):
return d.has_key(key) and d[key]

This returns either 0 or a list, which may be empty. In most cases, it is easier to use a function that always returns a list (maybe an empty one), such as:
它返回0或者一个列表,这个列表或许是空的。在大多数情况下,很容易使用一个一直返回一个列表(会许是一个空的)的函数,诸如:
def get_values_if_any(d, key):
return d.get(key, [])

You can use either of these functions in a statement. For example:
你能在一个语句里使用这些函数中的任何一个,例如
if get_values_if_any(d1, somekey):
if has_key_with_some_values(d1, somekey):

However, get_values_if_any is generally handier. For example, you can use it to check if 'freep' is among the values for somekey:
然而,get_values_if_any是更方便些。例如,你能使用它检查'freep'是否是一些键所对应值的一个

if 'freep' in get_values_if_any(d1, somekey):

This extra handiness comes from get_values_if_any always returning a list, rather than sometimes a list and sometimes 0.
这种便利来自于get_values_if_any 一直返回一个列表而不是有时候返回一个列表,有时候返回0

The first approach allows each value to be present multiple times for each given key. For example:
第一种方法允许每个值可以为每个被给的键表示多次,例如
example = {}
example.setdefault('a', []).append('apple')
example.setdefault('b', []).append('boots')
example.setdefault('c', []).append('cat')
example.setdefault('a', []).append('ant')
example.setdefault('a', []).append('apple')

Now example['a'] is ['apple', 'ant', 'apple']. If we now execute:
现在, example['a']是['apple', 'ant', 'apple']。 如果我们现在执行:
example['a'].remove('apple')

the following test is still satisfied:
下面的测试仍然是令人满意的
if 'apple' in example['a']

'apple' was present twice, and we removed it only once. (Testing for 'apple' with get_values_if_any(example, 'a') would be more general, although equivalent in this case.)
'apple'出现两次,并且我们仅仅移除一次。(为'apple', 做get_values_if_any(example, 'a')测试尽管相当于这种情况,但是更具普遍性)
The second approach, which eliminates duplications, requires rather similar idioms. Here's how to retrieve the list of the values for a key:
第二种方法,它消除重复,需要更合适的类似的惯用方法。这里是怎么样为一个键获得值的列表:
list_of_values = d2[key].keys( )

Here's how to remove a key/value pair, leaving empty dictionaries as items of d2 when the last value for a key is removed:
这里是怎么样移除一个键/值对,当这个键的最后一个值被除掉的时候,留下空的字典最为d2的元素:
del d2[key][value]

The has_key_with_some_values function shown earlier also works for the second approach, and you also have analogous alternatives, such as:
has_key_with_some_values 函数象更早显示的那样为第二种方法工作,你也有一个相似的选择,诸如:
def get_values_if_any(d, key):
return d.get(key, {}).keys( )

The second approach doesn't allow duplication. For example:
第二种方法不允许重复,例如
example = {}
example.setdefault('a', {})['apple']=1
example.setdefault('b', {})['boots']=1
example.setdefault('c', {})['cat']=1
example.setdefault('a', {})['ant']=1
example.setdefault('a', {})['apple']=1
Now example['a'] is {'apple':1, 'ant':1}. Now, if we execute:
现在example['a'] 是 {'apple':1, 'ant':1}。 现在,如果我们执行:
del example['a']['apple']

the following test is not satisfied:
下面的测试不能令人满意:
if 'apple' in example['a']
'apple' was present, but we just removed it.
'apple'出现,但是我们仅仅移除它。

This recipe focuses on how to code the raw functionality, but if you want to use this functionality in a systematic way, you'll want to wrap it up in a class. For that purpose, you need to make some of the design decisions that the recipe highlights. Do you want a value to be in the entry for a key multiple times? (Is the entry a bag rather than a set, in mathematical terms?) If so, should remove just reduce the number of occurrences by 1, or should it wipe out all of them? This is just the beginning of the choices you have to make, and the right choices depend on the specifics of your application.
这个配方关注怎么样编写原始的功能,但是如果你想在一个语法途径上使用这种功能,你将在一个类里包装它。为了那样的目的,你需要做一些设计决策来加强这个配方。你想一个在入口的值对应一个键多次吗?(对精确的术语来说,入口是一个包而不是一个集合?)如果是这样,应该是移除仅仅让重复的值的数目减少一个,或者是应该把他们全部消灭?这个是你不得不作出选择的开始,并且正确的选择依赖于你的特定的应用。
1.6.4 See Also
参考
The Library Reference section on mapping types.

[Original] [Print] [Top]
« Previous thread
[精华] Python 食谱--1.7:使用字典来分发
Python 编 程
19
Next thread »
[精华] Python 食谱--1.5:增加一个入口到字典里
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 04:11:40, cost 0.036839008331299 ms.