明确性与DRY原则——哪种方式更符合Pythonic风格?

4

我需要一个庞大的词典,主要包含一些典型值和一些独特的值,与IT技术有关。 获取该词典的第一种方法是定义一个扁平的“明确”的字典文本:

musicians = {
    'ABBA': 'pop',
    'Avril Lavigne': 'pop',
    ...
    'Mikhail Krug': 'russian chanson',
    'The Rolling Stones': 'rock',
    ...
    'Zaz': 'jazz',
}

第二个部分 - "DRY" 典型的列表和特殊项目字典:
pop_musicians = [
    'ABBA',
    'Avril Lavigne',
    ...
]

rock_musicians = [...]

unusual_musicians = {
    'Mikhail Krug': 'russian chanson',
    'Zaz': 'jazz',
}

musicians = dict(
    [(m, 'pop') for m in pop_musicians] +
    [(m, 'rock') for m in rock_musicians] +
    unusual_musicians.items()
)

假设我的情况下键值关系要更加多变(某些键的值可能会改变)。
你更喜欢哪种方式?为什么?在你看来,哪一种更符合Python风格?

1
我更喜欢第一种方法。它更易读,而且据我所知比你的第二种方法要短得多。此外,请记住这种类型的问题不适合在Stack Overflow上提问。这更多是一个品味或意见的问题。 - Hans Then
我对“Mikhail Krug”笑了。抱歉。 - Lev Levitsky
2
DRY并不一定意味着“尽可能简洁和压缩”。 - chepner
@chepner同意。我认为清晰度是最重要的价值。 - Gareth Latty
3
第二个解决方案(或Lattyware的备选版本)有一个巨大的优势:如果你必须输入1000次“pop”,至少会犯错一次...但正如Paul Manta所说,如果只有20个,第一个更容易阅读。 - abarnert
2个回答

9

我的回答是将您的数据结构分层:

genres = {
    "rock": [
        "some rock band",
        "some other rock band",
    ],
    "pop": [
        "some pop star",
        "some pop group",
    ],
}

如果你必须使用第一种格式,那么字典推导是一个很好的选择:

musicians = {musician: genre for genre, musicians in genres.items() for musician in musicians}

将产生:

{'some other rock band': 'rock', 'some pop group': 'pop', 'some rock band': 'rock', 'some pop star': 'pop'}

或者,如果你发现自己需要进行大量的复杂操作,可以考虑创建一个音乐家类来给自己更多的自由。


我还需要尽可能快地通过键检索值。扁平字典是必须的。 - leventov
3
如果你一定要使用那个数据结构(记住,过早优化是不明智的),那么可以使用字典推导式将其转换成所需的形式。请参考我更新后的答案。 - Gareth Latty
1
+1,因为这比OP的“DRY”解决方案更好(它更通用,结构如何配合更清晰,并且仍然保留了不必输入“pop” 1000次并希望您永远不会出现拼写错误的好处)。但更重要的是,在改进之前,您选择了他的“DRY”解决方案而不是他的“明确”解决方案,以及为什么选择。 - abarnert
很不幸,在我的情况下,对值(它们是函数)进行哈希没有太多意义。但我喜欢你的思维方式。 - leventov
@leventov 在Python中,函数和其他对象一样,是可哈希的 - 没有理由不将它们用作键。 - Gareth Latty

2
对于音乐家的短列表,第一种选项可能是最好的。如果你有相当大的列表,我会选择第二个选项。这样做没有任何不清楚的地方,可以减少输错的风险(如果字典很大,输错的可能性非常高),并且还可以将音乐家组织成视觉上不同的列表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接