我刚开始阅读Disted Peticolas关于Twisted(http://krondo.com/blog/?p=1247)的教程,并使用Python套接字快速浏览他的早期示例,我遇到了一行代码,我无法绕过头脑。代码在他的github上,特别是https://github.com/jdavisp3/twisted-intro/blob/master/async-client/get-poetry.py,但上下文并不重要。
以下是该行:
sock2task = dict([(s, i + 1) for i, s in enumerate(sockets)])
套接字是套接字列表。
此行将以
的形式创建字典{<sock3 object>: 3, <sock3 object>: 2, <sock3 object>: 1}
然而,我只是不明白如何。
试图得到一个等效的陈述,我想出了
sock2task = dict(enumerate(sockets, start=1))
然而这会导致
{1: <sock3 object>, 2: <sock3 object>, 3: <sock3 object>}
交换了键和值,反之亦然。
那它是如何运作的?在完整代码中,s或i都没有定义..
谢谢,马特
答案 0 :(得分:1)
您必须深入list comprehensions才能获得必要的背景资料。
尽管如此,您可以从对列表中创建字典,其中第一个值将被指定为键,第二个值将被指定为值。以下代码具有相同的想法,但它将帮助您了解它的工作原理。
#ifndef LISTTOOLS_H
#define LISTTOOLS_H
namespace LinkedListSavitch {
template<class T>
class Node {
public:
Node(const T& theData, Node<T>* theLink) : data(theData), link(theLink) {}
Node<T>* getLink() const {return link;}
const T getData() const {return data;}
void setData(const T& theData) {data = theData;}
void setLink(Node<T>* pointer) {link = pointer;}
private:
T data;
Node<T> *link;
};
template<class T>
void headInsert(Node<T>*& head, const T& theData);
template<class T>
void insert(Node<T>* afterMe, const T& theData);
template<class T>
void deleteNode(Node<T>* before);
template<class T>
void deleteFirstNode(Node<T>*& head);
template<class T>
Node<T>* search(Node<T>* head, const T& target);
} // LinkedListSavitch
#endif
您的代码获得了相反的结果,因为您没有反转result = {}
for index, s in enumerate(sockets):
result[s] = index + 1
返回的值(正如您在我的示例和原始代码中看到的那样)。
答案 1 :(得分:1)
您所涉及的行是使用列表推导初始化字典。要打破它:
dict可以像这样初始化
dict = dict([(key0, value0), ...)]) # make a dictionary out of a list of tuples
本书中的列表理解由以下部分组成:
1
# "for every index i and corresponding entry s in sockets"
for i, s in enumerate(sockets)
2
# a tuple of the socket s and its index + 1: `i + 1`
(s, i + 1)
3
# "Make a list in which for every index i
# and corresponding entry s in sockets there is a tuple (s, i + 1)"
[(s, i + 1) for i, s in enumerate(sockets)]
所以:
# "Convert this whole thing into a dictionary!"
dict([(s, i + 1) for i, s in enumerate(sockets)])
等效代码为:
sock2task = {}
for index, socket in enumerate(sockets):
sock2task[socket] = index + 1
输出的字典巧合地从3开始,因为字典没有被排序。
我希望现在更清楚了。
答案 2 :(得分:0)
sock2task = dict([(s, i + 1) for i, s in enumerate(sockets)])
^
这是一个列表理解+元组解包,强制转换为字典。
列表理解采用[f(i) for i in iterable]
的形式。在这种情况下,iterable
为enumerate(sockets)
,它会创建一个包含两个元素的元组。
元组可以解压缩。即i,j = (0,1)
会将0
分配给i
和1
分配给j
。
所以,基本上,i
和s
是在我有插入标记的位置创建的。
(顺便说一下,在python 2.7+中你也可以使用词典理解。sock2task = { s: i + 1 for i,s in enumerate(sockets)}