Python 将项目分组到存储桶中的简单方法

Python 将项目分组到存储桶中的简单方法,python,Python,我经常想用python存储一个无序的集合。做正确的事情,但几乎总是需要先对项目进行排序,并在使用迭代器之前捕获迭代器 有没有任何快速的方法可以通过标准的python模块或简单的python习惯用法获得这种行为 >>> bucket('thequickbrownfoxjumpsoverthelazydog', lambda x: x in 'aeiou') {False: ['t', 'h', 'q', 'c', 'k', 'b', 'r', 'w', 'n', 'f', 'x'

我经常想用python存储一个无序的集合。做正确的事情,但几乎总是需要先对项目进行排序,并在使用迭代器之前捕获迭代器

有没有任何快速的方法可以通过标准的python模块或简单的python习惯用法获得这种行为

>>> bucket('thequickbrownfoxjumpsoverthelazydog', lambda x: x in 'aeiou')
{False: ['t', 'h', 'q', 'c', 'k', 'b', 'r', 'w', 'n', 'f', 'x', 'j', 'm', 'p',
    's', 'v', 'r', 't', 'h', 'l', 'z', 'y', 'd', 'g'],
 True: ['e', 'u', 'i', 'o', 'o', 'u', 'o', 'e', 'e', 'a', 'o']}
>>> bucket(xrange(21), lambda x: x % 10)
{0: [0, 10, 20],
 1: [1, 11],
 2: [2, 12],
 3: [3, 13],
 4: [4, 14],
 5: [5, 15],
 6: [6, 16],
 7: [7, 17],
 8: [8, 18],
 9: [9, 19]}

这是一个简单的两行程序

d = {}
for x in "thequickbrownfoxjumpsoverthelazydog": d.setdefault(x in 'aeiou', []).append(x)
编辑:

只需添加另一个完整性案例

d={}
for x in xrange(21): d.setdefault(x%10, []).append(x)

这已经出现过好几次了-,在中有一个分区配方,但据我所知,在标准库中没有。。虽然几周前我对
积累
感到惊讶,但谁知道这些天在那里潜伏着什么呢?:^)

当我需要这种行为时,我使用

from collections import defaultdict

def partition(seq, key):
    d = defaultdict(list)
    for x in seq:
        d[key(x)].append(x)
    return d
继续我的一天

编辑:

以DSM的答案为起点,这里有一个更简洁、更一般的答案:

d = defaultdict(list)
map(lambda x: d[x in 'aeiou'].append(x),'thequickbrownfoxjumpsoverthelazydog')

# 这是一条两行线:

d = {False:[],True:[]}
filter(lambda x: d[True].append(x) if x in 'aeiou' else d[False].append(x),"thequickbrownfoxjumpedoverthelazydogs")
这当然可以做成一个班轮:

d = {False:[],True:[]};filter(lambda x: d[True].append(x) if x in 'aeiou' else d[False].append(x),"thequickbrownfoxjumpedoverthelazydogs")

当谓词为布尔值时,这里是上面的
partition()
的一个变体,避免了使用
dict
/
defaultdict

def boolpartition(seq, pred):
    passing, failing = [], []
    for item in seq:
        (passing if pred(item) else failing).append(item)
    return passing, failing
用法示例:

>>> even, odd = boolpartition([1, 2, 3, 4, 5], lambda x: x % 2 == 0)
>>> even
[2, 4]
>>> odd
[1, 3, 5]

如果是一个
pandas.DataFrame
,则以下功能也可以使用

屈服

0      0_1
1      0_0
2      0_0
[...]
如果不设置
标签
,则输出如下

0       (5.02, 5.74]
1      (4.296, 5.02]
2      (4.296, 5.02]
[...]

-1键并不总是假的和真的,它们应该是可调用的输出。我建议在“QuickBrownFoxJumpsOvertheLazyDog”中为x使用
:d[x在“aeiou”中]。附加(x)
表单(如格里夫的回答)。我真的不喜欢用
map
来处理副作用,然后扔掉它的值。格里夫斯回答的问题是,尽管它工作得很好,但计算成本要高一些。(它为每个元素调用setdefault,重复或不重复。)我喜欢DSMs的答案,但我想看看我是否能得到一行(或接近它。)如果你只是用
将两行连接在一起,它实际上不是一行!我不是说不要使用
defaultdict
,我的意思是将for循环更改为
map
,并不会使它更简洁,只会使它更混乱。+1对于defaultdict的使用,我总是忘记它的存在,我总是发现
defaultdict
比d.setdefault.etc类型更好tricks@wim:是的,我总是忘记它的存在。wim:事实上,我喜欢
setdefault
胜过
defaultdict
。这两种方式的代码量几乎相同,但是
setdefault
是明确的,你可以在现有的dict上使用它,因为你发现你需要它。我一定是通过询问“一行”来将讨论转向将所有内容塞进一行。我只是把它改成了“python习语”,但如果它真的很短,我当然不会抱怨。
0      0_1
1      0_0
2      0_0
[...]
0       (5.02, 5.74]
1      (4.296, 5.02]
2      (4.296, 5.02]
[...]