python - structure用法 - 新建一个字典




如何使用单个列表创建字典? (4)

你可以这样做:

>>> y = ['URL4','news1','news2','URL5','URL6','news1']
>>> result = {}
>>> current_url = None
>>> for entry in y:
...     if entry.startswith('URL'):
...         current_url = entry
...         result[current_url] = ()
...     else:
...         result[current_url] += (entry, )
...         
>>> result
{'URL4': ('news1', 'news2'), 'URL5': (), 'URL6': ('news1',)}

我有一个来自我国报纸网站的网址和标题列表。 作为一般例子:

x = ['URL1','news1','news2','news3','URL2','news1','news2','URL3','news1']

每个URL元素都有一个相应的'news'元素序列,其长度可以不同。 在上面的示例中,URL1有3个相应的新闻,而URL3只有一个。

有时URL没有相应的“新闻”元素:

y = ['URL4','news1','news2','URL5','URL6','news1']

我可以轻松找到每个URL的每个URL索引和“新闻”元素。

我的问题是: 是否可以将此列表转换为URL元素为键的字典,“news”元素是list / tuple-value?

预期产出

z = {'URL1':('news1', 'news2', 'news3'),
     'URL2':('news1', 'news2'),
     'URL3':('news1'),
     'URL4':('news1', 'news2'),
     'URL5':(),
     'URL6':('news1')}

我在这篇 post 看到了类似的问题,但它并没有解决我的问题。


使用 groupby ,one-liner的另一个解决方案:

x = ['URL1','news1','news2','news3','URL2','news1','news2','URL3','news1', 'URL4','news1','news2','URL5','URL6','news1']

from itertools import groupby

out = {k: tuple(v) for _, (k, *v) in groupby(x, lambda k, d={'g':0}: (d.update(g=d['g']+1), d['g']) if k.startswith('URL') else (None, d['g']))}

from pprint import pprint
pprint(out)

打印:

{'URL1': ('news1', 'news2', 'news3'),
 'URL2': ('news1', 'news2'),
 'URL3': ('news1',),
 'URL4': ('news1', 'news2'),
 'URL5': (),
 'URL6': ('news1',)}

您可以只使用列表中URL键的索引,并获取索引之间的内容并分配给第一个索引

像这样:

x = ['URL1','news1','news2','news3','URL2','news1','news2','URL3','news1']
urls = [x.index(y) for y in x if 'URL' in y]
adict = {}
for i in range(0, len(urls)):
    if i == len(urls)-1:
        adict[x[urls[i]]] = x[urls[i]+1:len(x)]
    else:
        adict[x[urls[i]]] = x[urls[i]+1:urls[i+1]]
print(adict)

输出:

{'URL1': ['news1', 'news2', 'news3'], 'URL2': ['news1', 'news2'], 'URL3': ['news1']}

more-itertools库 包含一个函数 split_before() ,它非常方便用于此目的:

{s[0]: tuple(s[1:]) for s in mt.split_before(x, lambda e: e.startswith('URL'))}

我认为这比在此之前发布的答案中的任何其他方法更清晰,但它确实引入了外部依赖(除非您重新实现该函数),这使得它不适合所有情况。

如果您的实际用例涉及真实URL或其他内容,而不是 URL# 形式的字符串,那么只需将 lambda e: e.startswith('URL') 替换为可用于选择除值之外的关键元素的任何函数元素。





dictionary