社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python:按键(元组)将字典拆分为更小的字典

Jaood • 5 年前 • 1665 次点击  

我有一本字典,其中的键是两个整数的元组 (x,y) 值是字符串。

如何将此词典拆分为较小的词典,其中的拆分取决于 y -价值大于某棵树?

例如,假设我有键(字典值不相关,所以我在这里省略它们)

(0, 2), (0, 4), (0, 10), (0, 3), (0, 11), (0, 20), (0, 8), (0, 14)

说我有树冠 0, 5, 10, 15 .

然后,一个拆分应该包含一个字典,其中包含以下键:

(0,2), (0,4), (0,3)

因为y值都大于0,但不大于5。

下一本字典应该有钥匙

(0,8)

因为它大于0和5,但不大于10。

然后我们有 (0, 10), (0, 11), (0, 14)

因为它大于(或等于)0,5,10,但不是15。

最后,我们 (0, 20) 独自一人。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/40247
 
1665 次点击  
文章 [ 4 ]  |  最新文章 5 年前
Rick Teachey
Reply   •   1 楼
Rick Teachey    6 年前

这种方法对我来说似乎很简单,但肯定不是最快的:

d1 = {(k1,k2):v for (k1,k2),v in d.items() if 0<k2<=5}
d2 = {(k1,k2):v for (k1,k2),v in d.items() if 5<k2<=10}
d3 = {(k1,k2):v for (k1,k2),v in d.items() if 10<k2<=15}
d4 = {(k1,k2):v for (k1,k2),v in d.items() if 15<k2}

或者像这样组合:

bounds = 0, 5, 10, 15, 1_000_000
bounds_dicts = {(b1,b2):{(k1,k2):v for (k1,k2),v in d.items() if b1<k2<=b2}
                for (b1,b2) in zip(bounds[:-1],bounds[1:])}

同样,这将是低效的。每一本新字典都要重复一次。但对于小问题,这应该是好的。

rajendra
Reply   •   2 楼
rajendra    6 年前

这应该管用。

original_dict = {(0, 2):"a", (0, 4):"b", (0, 10):"c",
 (0, 3):"d", (0, 11):"e", (0, 20):"f", (0, 8):"g", (0, 14):"h"}

thresholds = [0, 5, 10, 15]
thresholds = sorted(thresholds,reverse=True)
new_dict_of_dicts = {} #threshold: dict
for threshold in thresholds:
    new_dict_of_dicts[threshold] = {}
    for key in list(original_dict.keys()):
        if key[1] > threshold:
            new_dict_of_dicts[threshold][key] = original_dict.pop(key)

print(new_dict_of_dicts) 
#{15: {(0, 20): 'f'}, 10: {(0, 11): 'e', (0, 14): 'h'}, 5: {(0, 10): 'c', (0, 8): 'g'}, 0: {(0, 2): 'a', (0, 4): 'b', (0, 3): 'd'}}
user2263572
Reply   •   3 楼
user2263572    6 年前

当然这可以写得更好,但你应该明白。只需遍历dict,并根据可以动态定义或生成的各种条件检查键的y值。

thing = {
    (1,2): 'a',
    (2,19): 'b'
}

d1 = {}
d2 = {}
for k, v in thing.items():
    // while iterating through the original dict, write some logic to determine how you want to split up based on the y values.
    if k[1] < 5:
        d1[k] = v
    if k[1] < 10:
        d2[k] = v

print(d1, d2)
jpp
Reply   •   4 楼
jpp    6 年前

你可以使用 collections.defaultdict ,迭代和更新由bucket边界确定的键。这比创建可变数量的变量更好。

d = {(0, 2): 1, (0, 4): 2, (0, 10): 3, (0, 3): 4,
     (0, 11): 5, (0, 20): 6, (0, 8): 7, (0, 14): 8}

L = [0, 5, 10, 15, float('inf')]  # include infinite to facilitate later comparisons

from collections import defaultdict

dd = defaultdict(dict)

for k, v in d.items():
    for i, j in zip(L, L[1:]):
        if i <= k[1] < j:
            dd[i].update({k: v})
            break

print(dd)

defaultdict(dict,
            {0: {(0, 2): 1, (0, 3): 4, (0, 4): 2},
             5: {(0, 8): 7},
             10: {(0, 10): 3, (0, 11): 5, (0, 14): 8},
             15: {(0, 20): 6}})

该算法可以通过使用 bisect 而不是在 L 按顺序。