了解使用for i循环创建特定的python字典

时间:2015-07-08 19:17:22

标签: python for-loop dictionary

我刚开始阅读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都没有定义..

谢谢,马特

3 个答案:

答案 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]的形式。在这种情况下,iterableenumerate(sockets),它会创建一个包含两个元素的元组。

元组可以解压缩。即i,j = (0,1)会将0分配给i1分配给j

所以,基本上,is是在我有插入标记的位置创建的。

(顺便说一下,在python 2.7+中你也可以使用词典理解。sock2task = { s: i + 1 for i,s in enumerate(sockets)}