标签归档:dictionary

如何从sqlite查询中获取字典?

问题:如何从sqlite查询中获取字典?

db = sqlite.connect("test.sqlite")
res = db.execute("select * from table")

通过迭代,我得到了对应于行的列表。

for row in res:
    print row

我可以得到列的名称

col_name_list = [tuple[0] for tuple in res.description]

但是是否有一些功能或设置可以获取字典而不是列表?

{'col1': 'value', 'col2': 'value'}

还是我必须自己做?

db = sqlite.connect("test.sqlite")
res = db.execute("select * from table")

With iteration I get lists coresponding to the rows.

for row in res:
    print row

I can get name of the columns

col_name_list = [tuple[0] for tuple in res.description]

But is there some function or setting to get dictionaries instead of list?

{'col1': 'value', 'col2': 'value'}

or I have to do myself?


回答 0

您可以使用row_factory,如docs中的示例所示:

import sqlite3

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]

或按照文档中此示例之后给出的建议进行操作:

如果返回一个元组还不够,并且您希望基于名称的列访问,则应考虑将row_factory设置为高度优化的sqlite3.Row类型。Row提供对列的基于索引和不区分大小写的基于名称的访问,几乎没有内存开销。它可能比您自己的基于字典的自定义方法甚至基于db_row的解决方案都要好。

You could use row_factory, as in the example in the docs:

import sqlite3

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]

or follow the advice that’s given right after this example in the docs:

If returning a tuple doesn’t suffice and you want name-based access to columns, you should consider setting row_factory to the highly-optimized sqlite3.Row type. Row provides both index-based and case-insensitive name-based access to columns with almost no memory overhead. It will probably be better than your own custom dictionary-based approach or even a db_row based solution.


回答 1

我以为我已经回答了这个问题,即使亚当·施密德(Adam Schmideg)和亚历克斯·马特利(Alex Martelli)的回答中都提到了部分答案。为了让其他像我一样有相同问题的人,可以轻松找到答案。

conn = sqlite3.connect(":memory:")

#This is the important part, here we are setting row_factory property of
#connection object to sqlite3.Row(sqlite3.Row is an implementation of
#row_factory)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from stocks')

result = c.fetchall()
#returns a list of dictionaries, each item in list(each dictionary)
#represents a row of the table

I thought I answer this question even though the answer is partly mentioned in both Adam Schmideg’s and Alex Martelli’s answers. In order for others like me that have the same question, to find the answer easily.

conn = sqlite3.connect(":memory:")

#This is the important part, here we are setting row_factory property of
#connection object to sqlite3.Row(sqlite3.Row is an implementation of
#row_factory)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from stocks')

result = c.fetchall()
#returns a list of dictionaries, each item in list(each dictionary)
#represents a row of the table

回答 2

即使使用sqlite3.Row类-您仍然不能使用以下形式的字符串格式:

print "%(id)i - %(name)s: %(value)s" % row

为了解决这个问题,我使用了一个辅助函数,该函数接受行并将其转换为字典。我仅在字典对象比Row对象更可取时才使用它(例如,对于诸如字符串格式之类的东西,其中Row对象本身也不支持字典API)。但是其他所有时间都使用Row对象。

def dict_from_row(row):
    return dict(zip(row.keys(), row))       

Even using the sqlite3.Row class– you still can’t use string formatting in the form of:

print "%(id)i - %(name)s: %(value)s" % row

In order to get past this, I use a helper function that takes the row and converts to a dictionary. I only use this when the dictionary object is preferable to the Row object (e.g. for things like string formatting where the Row object doesn’t natively support the dictionary API as well). But use the Row object all other times.

def dict_from_row(row):
    return dict(zip(row.keys(), row))       

回答 3

连接到SQLite之后: con = sqlite3.connect(.....)只需运行即可:

con.row_factory = sqlite3.Row

瞧!

After you connect to SQLite: con = sqlite3.connect(.....) it is sufficient to just run:

con.row_factory = sqlite3.Row

Voila!


回答 4

PEP 249

Question: 

   How can I construct a dictionary out of the tuples returned by
   .fetch*():

Answer:

   There are several existing tools available which provide
   helpers for this task. Most of them use the approach of using
   the column names defined in the cursor attribute .description
   as basis for the keys in the row dictionary.

   Note that the reason for not extending the DB API specification
   to also support dictionary return values for the .fetch*()
   methods is that this approach has several drawbacks:

   * Some databases don't support case-sensitive column names or
     auto-convert them to all lowercase or all uppercase
     characters.

   * Columns in the result set which are generated by the query
     (e.g.  using SQL functions) don't map to table column names
     and databases usually generate names for these columns in a
     very database specific way.

   As a result, accessing the columns through dictionary keys
   varies between databases and makes writing portable code
   impossible.

所以是的,你自己做。

From PEP 249:

Question: 

   How can I construct a dictionary out of the tuples returned by
   .fetch*():

Answer:

   There are several existing tools available which provide
   helpers for this task. Most of them use the approach of using
   the column names defined in the cursor attribute .description
   as basis for the keys in the row dictionary.

   Note that the reason for not extending the DB API specification
   to also support dictionary return values for the .fetch*()
   methods is that this approach has several drawbacks:

   * Some databases don't support case-sensitive column names or
     auto-convert them to all lowercase or all uppercase
     characters.

   * Columns in the result set which are generated by the query
     (e.g.  using SQL functions) don't map to table column names
     and databases usually generate names for these columns in a
     very database specific way.

   As a result, accessing the columns through dictionary keys
   varies between databases and makes writing portable code
   impossible.

So yes, do it yourself.


回答 5

较短的版本:

db.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])

Shorter version:

db.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])

回答 6

在我的测试中最快:

conn.row_factory = lambda c, r: dict(zip([col[0] for col in c.description], r))
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.8 µs ± 1.05 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

vs:

conn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.4 µs ± 75.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

你决定 :)

Fastest on my tests:

conn.row_factory = lambda c, r: dict(zip([col[0] for col in c.description], r))
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.8 µs ± 1.05 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

vs:

conn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.4 µs ± 75.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

You decide :)


回答 7

与上述解决方案类似,但最紧凑:

db.row_factory = lambda C, R: { c[0]: R[i] for i, c in enumerate(C.description) }

Similar like before-mentioned solutions, but most compact:

db.row_factory = lambda C, R: { c[0]: R[i] for i, c in enumerate(C.description) }

回答 8

正如@gandalf的答案所提到的,必须使用conn.row_factory = sqlite3.Row,但是结果不是直接的字典。必须dict在上一个循环中添加一个附加的“ cast” :

import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute('create table t (a text, b text, c text)')
conn.execute('insert into t values ("aaa", "bbb", "ccc")')
conn.execute('insert into t values ("AAA", "BBB", "CCC")')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from t')
for r in c.fetchall():
    print(dict(r))

# {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
# {'a': 'AAA', 'b': 'BBB', 'c': 'CCC'}

As mentioned by @gandalf’s answer, one has to use conn.row_factory = sqlite3.Row, but the results are not directly dictionaries. One has to add an additional “cast” to dict in the last loop:

import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute('create table t (a text, b text, c text)')
conn.execute('insert into t values ("aaa", "bbb", "ccc")')
conn.execute('insert into t values ("AAA", "BBB", "CCC")')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from t')
for r in c.fetchall():
    print(dict(r))

# {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
# {'a': 'AAA', 'b': 'BBB', 'c': 'CCC'}

回答 9

我认为您在正确的轨道上。让我们保持非常简单并完成您要执行的操作:

import sqlite3
db = sqlite3.connect("test.sqlite3")
cur = db.cursor()
res = cur.execute("select * from table").fetchall()
data = dict(zip([c[0] for c in cur.description], res[0]))

print(data)

缺点是.fetchall(),这是您消耗内存的谋杀手段,如果表很大。但是对于仅处理数千行文本和数字列的琐碎应用程序而言,这种简单的方法就足够了。

对于严重的问题,您应该按照其他许多答案中的建议研究行工厂。

I think you were on the right track. Let’s keep this very simple and complete what you were trying to do:

import sqlite3
db = sqlite3.connect("test.sqlite3")
cur = db.cursor()
res = cur.execute("select * from table").fetchall()
data = dict(zip([c[0] for c in cur.description], res[0]))

print(data)

The downside is that .fetchall(), which is murder on your memory consumption, if your table is very large. But for trivial applications dealing with mere few thousands of rows of text and numeric columns, this simple approach is good enough.

For serious stuff, you should look into row factories, as proposed in many other answers.


回答 10

或者,您可以按以下方式将sqlite3.Rows转换为字典。这将为字典提供每一行的列表。

    def from_sqlite_Row_to_dict(list_with_rows):
    ''' Turn a list with sqlite3.Row objects into a dictionary'''
    d ={} # the dictionary to be filled with the row data and to be returned

    for i, row in enumerate(list_with_rows): # iterate throw the sqlite3.Row objects            
        l = [] # for each Row use a separate list
        for col in range(0, len(row)): # copy over the row date (ie. column data) to a list
            l.append(row[col])
        d[i] = l # add the list to the dictionary   
    return d

Or you could convert the sqlite3.Rows to a dictionary as follows. This will give a dictionary with a list for each row.

    def from_sqlite_Row_to_dict(list_with_rows):
    ''' Turn a list with sqlite3.Row objects into a dictionary'''
    d ={} # the dictionary to be filled with the row data and to be returned

    for i, row in enumerate(list_with_rows): # iterate throw the sqlite3.Row objects            
        l = [] # for each Row use a separate list
        for col in range(0, len(row)): # copy over the row date (ie. column data) to a list
            l.append(row[col])
        d[i] = l # add the list to the dictionary   
    return d

回答 11

通用替代方案,仅使用三行

def select_column_and_value(db, sql, parameters=()):
    execute = db.execute(sql, parameters)
    fetch = execute.fetchone()
    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

con = sqlite3.connect('/mydatabase.db')
c = con.cursor()
print(select_column_and_value(c, 'SELECT * FROM things WHERE id=?', (id,)))

但是,如果您的查询未返回任何内容,将导致错误。在这种情况下…

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {k[0]: None for k in execute.description}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

要么

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

A generic alternative, using just three lines

def select_column_and_value(db, sql, parameters=()):
    execute = db.execute(sql, parameters)
    fetch = execute.fetchone()
    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

con = sqlite3.connect('/mydatabase.db')
c = con.cursor()
print(select_column_and_value(c, 'SELECT * FROM things WHERE id=?', (id,)))

But if your query returns nothing, will result in error. In this case…

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {k[0]: None for k in execute.description}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

or

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

回答 12

import sqlite3

db = sqlite3.connect('mydatabase.db')
cursor = db.execute('SELECT * FROM students ORDER BY CREATE_AT')
studentList = cursor.fetchall()

columnNames = list(map(lambda x: x[0], cursor.description)) #students table column names list
studentsAssoc = {} #Assoc format is dictionary similarly


#THIS IS ASSOC PROCESS
for lineNumber, student in enumerate(studentList):
    studentsAssoc[lineNumber] = {}

    for columnNumber, value in enumerate(student):
        studentsAssoc[lineNumber][columnNames[columnNumber]] = value


print(studentsAssoc)

结果肯定是正确的,但我不知道最好的。

import sqlite3

db = sqlite3.connect('mydatabase.db')
cursor = db.execute('SELECT * FROM students ORDER BY CREATE_AT')
studentList = cursor.fetchall()

columnNames = list(map(lambda x: x[0], cursor.description)) #students table column names list
studentsAssoc = {} #Assoc format is dictionary similarly


#THIS IS ASSOC PROCESS
for lineNumber, student in enumerate(studentList):
    studentsAssoc[lineNumber] = {}

    for columnNumber, value in enumerate(student):
        studentsAssoc[lineNumber][columnNames[columnNumber]] = value


print(studentsAssoc)

The result is definitely true, but I do not know the best.


回答 13

python中的字典提供对元素的任意访问。因此,任何带有“名称”的词典,尽管一方面可能会提供更多信息(又称字段名称),却会使字段“无序”,这可能是不必要的。

最好的方法是将名称放在单独的列表中,然后根据需要自己将其与结果组合。

try:
         mycursor = self.memconn.cursor()
         mycursor.execute('''SELECT * FROM maintbl;''')
         #first get the names, because they will be lost after retrieval of rows
         names = list(map(lambda x: x[0], mycursor.description))
         manyrows = mycursor.fetchall()

         return manyrows, names

还请记住,在所有方法中,名称都是您在查询中提供的名称,而不是数据库中的名称。exceptions是SELECT * FROM

如果您唯一关心的是使用字典来获得结果,则一定要使用conn.row_factory = sqlite3.Row(已经在另一个答案中说明了)。

Dictionaries in python provide arbitrary access to their elements. So any dictionary with “names” although it might be informative on one hand (a.k.a. what are the field names) “un-orders” the fields, which might be unwanted.

Best approach is to get the names in a separate list and then combine them with the results by yourself, if needed.

try:
         mycursor = self.memconn.cursor()
         mycursor.execute('''SELECT * FROM maintbl;''')
         #first get the names, because they will be lost after retrieval of rows
         names = list(map(lambda x: x[0], mycursor.description))
         manyrows = mycursor.fetchall()

         return manyrows, names

Also remember that the names, in all approaches, are the names you provided in the query, not the names in database. Exception is the SELECT * FROM

If your only concern is to get the results using a dictionary, then definitely use the conn.row_factory = sqlite3.Row (already stated in another answer).


通过索引访问Python字典的元素

问题:通过索引访问Python字典的元素

考虑一个像

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

例如,如何访问该词典的特定元素?例如,我想在对Apple的第一个元素进行某种格式设置后再打印第一个元素,在我们的例子中,该格式仅是“ American”?

附加信息上面的数据结构是通过在python函数中解析输入文件创建的。一旦创建,它在该运行中将保持不变。

我在函数中使用此数据结构。

因此,如果文件发生更改,则下次运行此应用程序时,文件的内容将有所不同,因此此数据结构的内容将有所不同,但格式将相同。因此,您在我的职能中看到我,我不知道Apple中的第一个元素是“ American”或其他任何元素,因此我不能直接使用“ American”作为键。

Consider a dict like

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

How do I access for instance a particular element of this dictionary? for instance, I would like to print the first element after some formatting the first element of Apple which in our case is ‘American’ only?

Additional information The above data structure was created by parsing an input file in a python function. Once created however it remains the same for that run.

I am using this data structure in my function.

So if the file changes, the next time this application is run the contents of the file are different and hence the contents of this data structure will be different but the format would be the same. So you see I in my function I don’t know that the first element in Apple is ‘American’ or anything else so I can’t directly use ‘American’ as a key.


回答 0

鉴于它是字典,您可以使用键来访问它。获取存储在“ Apple”下的词典,请执行以下操作:

>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}

并让其中有多少是美国人(16),请执行以下操作:

>>> mydict["Apple"]["American"]
'16'

Given that it is a dictionary you access it by using the keys. Getting the dictionary stored under “Apple”, do the following:

>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}

And getting how many of them are American (16), do like this:

>>> mydict["Apple"]["American"]
'16'

回答 1

如果问题是,如果我知道我有一个包含“ Apple”作为水果和“ American”作为一种苹果的字典,我将使用:

myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
          'Grapes':{'Arabian':'25','Indian':'20'} }


print myDict['Apple']['American']

正如其他人建议的那样。如果问题是,则当您将任意文件读入dict数据结构的dict中时,您不知道是否存在“ Apple”作为水果,是否存在“ American”作为“ Apple”类型,您可以执行以下操作:

print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]

还是更好,所以如果您知道只有Apple拥有American类型,就不必不必要地遍历整个dict。

if 'Apple' in myDict:
    if 'American' in myDict['Apple']:
        print myDict['Apple']['American']

在所有这些情况下,字典实际存储条目的顺序都无关紧要。如果您确实担心订单,则可以考虑使用OrderedDict

http://docs.python.org/dev/library/collections.html#collections.OrderedDict

If the questions is, if I know that I have a dict of dicts that contains ‘Apple’ as a fruit and ‘American’ as a type of apple, I would use:

myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
          'Grapes':{'Arabian':'25','Indian':'20'} }


print myDict['Apple']['American']

as others suggested. If instead the questions is, you don’t know whether ‘Apple’ as a fruit and ‘American’ as a type of ‘Apple’ exist when you read an arbitrary file into your dict of dict data structure, you could do something like:

print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]

or better yet so you don’t unnecessarily iterate over the entire dict of dicts if you know that only Apple has the type American:

if 'Apple' in myDict:
    if 'American' in myDict['Apple']:
        print myDict['Apple']['American']

In all of these cases it doesn’t matter what order the dictionaries actually store the entries. If you are really concerned about the order, then you might consider using an OrderedDict:

http://docs.python.org/dev/library/collections.html#collections.OrderedDict


回答 2

正如我注意到您的描述一样,您只知道解析器将为您提供一个字典,其值也就是字典,如下所示:

sampleDict = {
              "key1": {"key10": "value10", "key11": "value11"},
              "key2": {"key20": "value20", "key21": "value21"}
              }

因此,您必须迭代父词典。如果要打印或访问sampleDict.values()列表中的所有第一个词典键,则可以使用以下方法:

for key, value in sampleDict.items():
    print value.keys()[0]

如果您只想访问中第一个项目的第一个键sampleDict.values(),这可能会很有用:

print sampleDict.values()[0].keys()[0]

如果使用您在问题中给出的示例,我的意思是:

sampleDict = {
              'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
              'Grapes':{'Arabian':'25','Indian':'20'}
              }

第一个代码的输出是:

American
Indian

第二个代码的输出是:

American

As I noticed your description, you just know that your parser will give you a dictionary that its values are dictionary too like this:

sampleDict = {
              "key1": {"key10": "value10", "key11": "value11"},
              "key2": {"key20": "value20", "key21": "value21"}
              }

So you have to iterate over your parent dictionary. If you want to print out or access all first dictionary keys in sampleDict.values() list, you may use something like this:

for key, value in sampleDict.items():
    print value.keys()[0]

If you want to just access first key of the first item in sampleDict.values(), this may be useful:

print sampleDict.values()[0].keys()[0]

If you use the example you gave in the question, I mean:

sampleDict = {
              'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
              'Grapes':{'Arabian':'25','Indian':'20'}
              }

The output for the first code is:

American
Indian

And the output for the second code is:

American

EDIT 1:

Above code examples does not work for version 3 and above of python; since from version 3, python changed the type of output of methods keys and values from list to dict_values. Type dict_values is not accepting indexing, but it is iterable. So you need to change above codes as below:

First One:

for key, value in sampleDict.items():
    print(list(value.keys())[0])

Second One:

print(list(list(sampleDict.values())[0].keys())[0])

回答 3

作为奖励,我想为您的问题提供一种不同的解决方案。您似乎正在处理嵌套字典,这通常很乏味,尤其是当您必须检查内部键的存在时。

在pypi上有一些与此有关的有趣库,这是您的快速搜索

在您的特定情况下,dict_digger似乎很合适。

>>> import dict_digger
>>> d = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} 
}

>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None

As a bonus, I’d like to offer kind of a different solution to your issue. You seem to be dealing with nested dictionaries, which is usually tedious, especially when you have to check for existence of an inner key.

There are some interesting libraries regarding this on pypi, here is a quick search for you.

In your specific case, dict_digger seems suited.

>>> import dict_digger
>>> d = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} 
}

>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None

回答 4

您可以使用dict['Apple'].keys()[0]获取Apple字典中的第一个键,但是不能保证它会是American。词典中键的顺序可以根据词典的内容和键的添加顺序而变化。

You can use dict['Apple'].keys()[0] to get the first key in the Apple dictionary, but there’s no guarantee that it will be American. The order of keys in a dictionary can change depending on the contents of the dictionary and the order the keys were added.


回答 5

我知道这是8岁,但似乎没有人真正阅读并回答过这个问题。

您可以在字典上调用.values()以获得内部字典的列表,从而按索引访问它们。

>>> mydict = {
...  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
...  'Grapes':{'Arabian':'25','Indian':'20'} }

>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}

>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']

I know this is 8 years old, but no one seems to have actually read and answered the question.

You can call .values() on a dict to get a list of the inner dicts and thus access them by index.

>>> mydict = {
...  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
...  'Grapes':{'Arabian':'25','Indian':'20'} }

>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}

>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']

回答 6

您不能依赖字典的顺序。但是您可以尝试以下方法:

dict['Apple'].items()[0][0]

如果您希望保留订单,则可以使用以下网址http : //www.python.org/dev/peps/pep-0372/#ordered-dict-api

You can’t rely on order on dictionaries. But you may try this:

dict['Apple'].items()[0][0]

If you want the order to be preserved you may want to use this: http://www.python.org/dev/peps/pep-0372/#ordered-dict-api


回答 7

简单示例以了解如何访问字典中的元素:-

创建字典

d = {'dog' : 'bark', 'cat' : 'meow' } 
print(d.get('cat'))
print(d.get('lion'))
print(d.get('lion', 'Not in the dictionary'))
print(d.get('lion', 'NA'))
print(d.get('dog', 'NA'))

探索有关Python词典的更多信息,并在此处进行交互学习…

Simple Example to understand how to access elements in the dictionary:-

Create a Dictionary

d = {'dog' : 'bark', 'cat' : 'meow' } 
print(d.get('cat'))
print(d.get('lion'))
print(d.get('lion', 'Not in the dictionary'))
print(d.get('lion', 'NA'))
print(d.get('dog', 'NA'))

Explore more about Python Dictionaries and learn interactively here…


回答 8

尽管有很多问题的答案,但很少有人指出字典是无序的映射,因此(直到使用Python 3.7祝福插入顺序)字典中“第一个”条目的想法实际上是没道理 甚至OrderedDict只能通过使用诸如以下的丑陋的数字索引来访问mydict[mydict.keys()[0]](仅Python 2,因为在Python 3中keys()是不可下标的迭代器。)

从3.7开始,并在3,6中付诸实践-引入了新的行为,但直到3.7才包含在语言规范中-在字典的键,值或项上进行迭代(我相信,也设置)将首先产生最近插入的对象。仍然没有简单的方法可以通过数字插入索引来访问它们。

关于选择和“格式化”项目的问题,如果您知道要在字典中检索的键,通常可以将该键用作下标来检索它(my_var = mydict['Apple'])。

如果您确实希望能够通过条目号为项目建立索引(而忽略了特定条目号会随着插入而改变的事实),那么适当的结构可能就是一个由两个元素组成的元组的列表。代替

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

您可以使用:

mylist = [
    ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
    ('Grapes', {'Arabian': '25', 'Indian': '20'}
]

在这种情况下,第一个条目采用mylist[0]经典的列表扩展名形式,其值为('Apple', {'American':'16', 'Mexican':10, 'Chinese':5})。您可以如下遍历整个列表:

for (key, value) in mylist:  # unpacks to avoid tuple indexing
    if key == 'Apple':
        if 'American' in value:
            print(value['American'])

但是,如果您知道要查找键“ Apple”,那么为什么不使用字典呢?

您可以通过缓存键列表来引入更高级别的间接访问,但是保持两个数据结构同步的复杂性将不可避免地增加代码的复杂性。

Few people appear, despite the many answers to this question, to have pointed out that dictionaries are un-ordered mappings, and so (until the blessing of insertion order with Python 3.7) the idea of the “first” entry in a dictionary literally made no sense. And even an OrderedDict can only be accessed by numerical index using such uglinesses as mydict[mydict.keys()[0]] (Python 2 only, since in Python 3 keys() is a non-subscriptable iterator.)

From 3.7 onwards and in practice in 3,6 as well – the new behaviour was introduced then, but not included as part of the language specification until 3.7 – iteration over the keys, values or items of a dict (and, I believe, a set also) will yield the least-recently inserted objects first. There is still no simple way to access them by numerical index of insertion.

As to the question of selecting and “formatting” items, if you know the key you want to retrieve in the dictionary you would normally use the key as a subscript to retrieve it (my_var = mydict['Apple']).

If you really do want to be able to index the items by entry number (ignoring the fact that a particular entry’s number will change as insertions are made) then the appropriate structure would probably be a list of two-element tuples. Instead of

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

you might use:

mylist = [
    ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
    ('Grapes', {'Arabian': '25', 'Indian': '20'}
]

Under this regime the first entry is mylist[0] in classic list-endexed form, and its value is ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). You could iterate over the whole list as follows:

for (key, value) in mylist:  # unpacks to avoid tuple indexing
    if key == 'Apple':
        if 'American' in value:
            print(value['American'])

but if you know you are looking for the key “Apple”, why wouldn’t you just use a dict instead?

You could introduce an additional level of indirection by cacheing the list of keys, but the complexities of keeping two data structures in synchronisation would inevitably add to the complexity of your code.


回答 9

使用以下小功能,挖掘树形字典变得非常容易:

def dig(tree, path):
    for key in path.split("."):
        if isinstance(tree, dict) and tree.get(key):
            tree = tree[key]
        else:
            return None
    return tree

现在,dig(mydict, "Apple.Mexican")返回10,而dig(mydict, "Grape")产生子树{'Arabian':'25','Indian':'20'}。如果字典中不包含键,则dig返回None

请注意,您可以轻松地从’。’更改(甚至参数化)分隔符char。到“ /”,“ |” 等等

With the following small function, digging into a tree-shaped dictionary becomes quite easy:

def dig(tree, path):
    for key in path.split("."):
        if isinstance(tree, dict) and tree.get(key):
            tree = tree[key]
        else:
            return None
    return tree

Now, dig(mydict, "Apple.Mexican") returns 10, while dig(mydict, "Grape") yields the subtree {'Arabian':'25','Indian':'20'}. If a key is not contained in the dictionary, dig returns None.

Note that you can easily change (or even parameterize) the separator char from ‘.’ to ‘/’, ‘|’ etc.


从字典中删除带有空字符串的键的有效方法

问题:从字典中删除带有空字符串的键的有效方法

我有一个字典,想删除所有有空值字符串的键。

metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)',
            u'EXIF:CFAPattern2': u''}

做这个的最好方式是什么?

I have a dict and would like to remove all the keys for which there are empty value strings.

metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)',
            u'EXIF:CFAPattern2': u''}

What is the best way to do this?


回答 0

Python 2.X

dict((k, v) for k, v in metadata.iteritems() if v)

Python 2.7-3.X

{k: v for k, v in metadata.items() if v is not None}

请注意,您所有的键都有值。只是其中一些值是空字符串。没有值的字典中就没有键。如果它没有价值,就不会在字典中。

Python 2.X

dict((k, v) for k, v in metadata.iteritems() if v)

Python 2.7 – 3.X

{k: v for k, v in metadata.items() if v is not None}

Note that all of your keys have values. It’s just that some of those values are the empty string. There’s no such thing as a key in a dict without a value; if it didn’t have a value, it wouldn’t be in the dict.


回答 1

它甚至比BrenBarn的解决方案还短(我认为它更具可读性)

{k: v for k, v in metadata.items() if v}

使用Python 2.7.3测试。

It can get even shorter than BrenBarn’s solution (and more readable I think)

{k: v for k, v in metadata.items() if v}

Tested with Python 2.7.3.


回答 2

如果您确实需要修改原始词典:

empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
    del metadata[k]

请注意,我们必须列出一个空键,因为我们无法在遍历字典时修改字典(您可能已经注意到)。但是,这(在内存方面)比创建全新的字典便宜(除非存在大量具有空值的条目)。

If you really need to modify the original dictionary:

empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
    del metadata[k]

Note that we have to make a list of the empty keys because we can’t modify a dictionary while iterating through it (as you may have noticed). This is less expensive (memory-wise) than creating a brand-new dictionary, though, unless there are a lot of entries with empty values.


回答 3

BrenBarn的解决方案是理想的(我可能会添加pythonic)。但是,这是另一个(fp)解决方案:

from operator import itemgetter
dict(filter(itemgetter(1), metadata.items()))

BrenBarn’s solution is ideal (and pythonic, I might add). Here is another (fp) solution, however:

from operator import itemgetter
dict(filter(itemgetter(1), metadata.items()))

回答 4

如果您想要一种功能全面但简洁的方法来处理通常是嵌套的甚至可能包含循环的现实世界数据结构,建议您从boltons实用程序包中查看remap实用程序

之后pip install boltons或复制iterutils.py到您的项目,只是做:

from boltons.iterutils import remap

drop_falsey = lambda path, key, value: bool(value)
clean = remap(metadata, visit=drop_falsey)

该页面上有更多示例,包括使用Github API处理更大对象的示例。

它是纯Python,因此可在任何地方使用,并已在Python 2.7和3.3+中进行了全面测试。最棒的是,我是针对这种情况编写的,因此,如果您发现它无法处理的情况,可以在这里麻烦我进行修复。

If you want a full-featured, yet succinct approach to handling real-world data structures which are often nested, and can even contain cycles, I recommend looking at the remap utility from the boltons utility package.

After pip install boltons or copying iterutils.py into your project, just do:

from boltons.iterutils import remap

drop_falsey = lambda path, key, value: bool(value)
clean = remap(metadata, visit=drop_falsey)

This page has many more examples, including ones working with much larger objects from Github’s API.

It’s pure-Python, so it works everywhere, and is fully tested in Python 2.7 and 3.3+. Best of all, I wrote it for exactly cases like this, so if you find a case it doesn’t handle, you can bug me to fix it right here.


回答 5

基于Ryan的解决方案,如果您还有列表和嵌套字典:

对于Python 2:

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.iteritems() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

对于Python 3:

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.items() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

Based on Ryan’s solution, if you also have lists and nested dictionaries:

For Python 2:

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.iteritems() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

For Python 3:

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.items() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

回答 6

如果您有一个嵌套的字典,并且希望它甚至对空的子元素也适用,则可以使用BrenBarn建议的递归变体:

def scrub_dict(d):
    if type(d) is dict:
        return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
    else:
        return d

If you have a nested dictionary, and you want this to work even for empty sub-elements, you can use a recursive variant of BrenBarn’s suggestion:

def scrub_dict(d):
    if type(d) is dict:
        return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
    else:
        return d

回答 7

快速解答(TL; DR)

范例01

### example01 -------------------

mydict  =   { "alpha":0,
              "bravo":"0",
              "charlie":"three",
              "delta":[],
              "echo":False,
              "foxy":"False",
              "golf":"",
              "hotel":"   ",                        
            }
newdict =   dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(vdata) ])
print newdict

### result01 -------------------
result01 ='''
{'foxy': 'False', 'charlie': 'three', 'bravo': '0'}
'''

详细答案

问题

  • 内容: Python 2.x
  • 场景:开发人员希望修改字典以排除空白值
    • aka从字典中删除空值
    • 也就是删除具有空白值的键
    • aka过滤器字典,用于每个键值对上的非空白值

  • example01使用带有简单条件的python list-comprehension语法删除“空”值

陷阱

  • example01仅对原始词典的副本进行操作(未就地修改)
  • example01可能会产生意外结果,具体取决于开发人员“空”的含义
    • 开发人员是否打算保留虚假的价值
    • 如果字典中的值不保证是字符串,则开发人员可能会意外丢失数据。
    • result01显示原始集合中仅保留了三个键值对

替代示例

  • example02帮助解决潜在的陷阱
  • 该方法是通过更改条件使用“空”的更精确定义。
  • 在这里,我们只想滤除评估为空字符串的值。
  • 在这里,我们还使用.strip()过滤出仅包含空格的值。

示例02

### example02 -------------------

mydict  =   { "alpha":0,
              "bravo":"0",
              "charlie":"three",
              "delta":[],
              "echo":False,
              "foxy":"False",
              "golf":"",
              "hotel":"   ",
            }
newdict =   dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(str(vdata).strip()) ])
print newdict

### result02 -------------------
result02 ='''
{'alpha': 0,
  'bravo': '0', 
  'charlie': 'three', 
  'delta': [],
  'echo': False,
  'foxy': 'False'
  }
'''

也可以看看

Quick Answer (TL;DR)

Example01

### example01 -------------------

mydict  =   { "alpha":0,
              "bravo":"0",
              "charlie":"three",
              "delta":[],
              "echo":False,
              "foxy":"False",
              "golf":"",
              "hotel":"   ",                        
            }
newdict =   dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(vdata) ])
print newdict

### result01 -------------------
result01 ='''
{'foxy': 'False', 'charlie': 'three', 'bravo': '0'}
'''

Detailed Answer

Problem

  • Context: Python 2.x
  • Scenario: Developer wishes modify a dictionary to exclude blank values
    • aka remove empty values from a dictionary
    • aka delete keys with blank values
    • aka filter dictionary for non-blank values over each key-value pair

Solution

  • example01 use python list-comprehension syntax with simple conditional to remove “empty” values

Pitfalls

  • example01 only operates on a copy of the original dictionary (does not modify in place)
  • example01 may produce unexpected results depending on what developer means by “empty”
    • Does developer mean to keep values that are falsy?
    • If the values in the dictionary are not gauranteed to be strings, developer may have unexpected data loss.
    • result01 shows that only three key-value pairs were preserved from the original set

Alternate example

  • example02 helps deal with potential pitfalls
  • The approach is to use a more precise definition of “empty” by changing the conditional.
  • Here we only want to filter out values that evaluate to blank strings.
  • Here we also use .strip() to filter out values that consist of only whitespace.

Example02

### example02 -------------------

mydict  =   { "alpha":0,
              "bravo":"0",
              "charlie":"three",
              "delta":[],
              "echo":False,
              "foxy":"False",
              "golf":"",
              "hotel":"   ",
            }
newdict =   dict([(vkey, vdata) for vkey, vdata in mydict.iteritems() if(str(vdata).strip()) ])
print newdict

### result02 -------------------
result02 ='''
{'alpha': 0,
  'bravo': '0', 
  'charlie': 'three', 
  'delta': [],
  'echo': False,
  'foxy': 'False'
  }
'''

See also


回答 8

对于python 3

dict((k, v) for k, v in metadata.items() if v)

For python 3

dict((k, v) for k, v in metadata.items() if v)

回答 9

patriciasznneonneo的答案为基础,并考虑到您可能希望删除仅包含某些虚假内容(例如'')但没有其他虚假内容(例如)的密钥的可能性0,或者您甚至想包含一些真实的内容(例如'SPAM') ,那么您可以制作一个非常具体的命中列表:

unwanted = ['', u'', None, False, [], 'SPAM']

不幸的是,这并不是很有效,因为例如0 in unwanted计算结果为True。我们需要区分0和其他虚假的东西,所以我们必须使用is

any([0 is i for i in unwanted])

…评估为False

现在将其用于del不需要的东西:

unwanted_keys = [k for k, v in metadata.items() if any([v is i for i in unwanted])]
for k in unwanted_keys: del metadata[k]

如果您想要一个新的字典,而不是metadata就地修改:

newdict = {k: v for k, v in metadata.items() if not any([v is i for i in unwanted])}

Building on the answers from patriciasz and nneonneo, and accounting for the possibility that you might want to delete keys that have only certain falsy things (e.g. '') but not others (e.g. 0), or perhaps you even want to include some truthy things (e.g. 'SPAM'), then you could make a highly specific hitlist:

unwanted = ['', u'', None, False, [], 'SPAM']

Unfortunately, this doesn’t quite work, because for example 0 in unwanted evaluates to True. We need to discriminate between 0 and other falsy things, so we have to use is:

any([0 is i for i in unwanted])

…evaluates to False.

Now use it to del the unwanted things:

unwanted_keys = [k for k, v in metadata.items() if any([v is i for i in unwanted])]
for k in unwanted_keys: del metadata[k]

If you want a new dictionary, instead of modifying metadata in place:

newdict = {k: v for k, v in metadata.items() if not any([v is i for i in unwanted])}

回答 10

我阅读了该线程中的所有答复,并且也引用了该线程: 使用递归函数删除嵌套字典中的空字典

我最初在这里使用解决方案,效果很好:

尝试1:太热(不具有性能或过时的能力)

def scrub_dict(d):
    if type(d) is dict:
        return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
    else:
        return d

但是在Python 2.7世界中提出了一些性能和兼容性问题:

  1. isinstance代替type
  2. 将列表组合展开到for循环中以提高效率
  3. 使用python3安全items而不是iteritems

尝试2:太冷(缺乏记忆)

def scrub_dict(d):
    new_dict = {}
    for k, v in d.items():
        if isinstance(v,dict):
            v = scrub_dict(v)
        if not v in (u'', None, {}):
            new_dict[k] = v
    return new_dict

DOH!这不是递归的,也不是完全的记忆。

尝试3:正确(到目前为止)

def scrub_dict(d):
    new_dict = {}
    for k, v in d.items():
        if isinstance(v,dict):
            v = scrub_dict(v)
        if not v in (u'', None, {}):
            new_dict[k] = v
    return new_dict

I read all replies in this thread and some referred also to this thread: Remove empty dicts in nested dictionary with recursive function

I originally used solution here and it worked great:

Attempt 1: Too Hot (not performant or future-proof):

def scrub_dict(d):
    if type(d) is dict:
        return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
    else:
        return d

But some performance and compatibility concerns were raised in Python 2.7 world:

  1. use isinstance instead of type
  2. unroll the list comp into for loop for efficiency
  3. use python3 safe items instead of iteritems

Attempt 2: Too Cold (Lacks Memoization):

def scrub_dict(d):
    new_dict = {}
    for k, v in d.items():
        if isinstance(v,dict):
            v = scrub_dict(v)
        if not v in (u'', None, {}):
            new_dict[k] = v
    return new_dict

DOH! This is not recursive and not at all memoizant.

Attempt 3: Just Right (so far):

def scrub_dict(d):
    new_dict = {}
    for k, v in d.items():
        if isinstance(v,dict):
            v = scrub_dict(v)
        if not v in (u'', None, {}):
            new_dict[k] = v
    return new_dict

回答 11

带数组的字典

  • 在答案尝试3:刚刚好(到目前为止)BlissRage的回答不能正确处理数组中的元素。我会附上一个补丁,以防有人需要。该方法使用带有的语句块处理列表,该语句块if isinstance(v, list):使用原始scrub_dict(d)实现清理列表。
    @staticmethod
    def scrub_dict(d):
        new_dict = {}
        for k, v in d.items():
            if isinstance(v, dict):
                v = scrub_dict(v)
            if isinstance(v, list):
                v = scrub_list(v)
            if not v in (u'', None, {}):
                new_dict[k] = v
        return new_dict

    @staticmethod
    def scrub_list(d):
        scrubbed_list = []
        for i in d:
            if isinstance(i, dict):
                i = scrub_dict(i)
            scrubbed_list.append(i)
        return scrubbed_list

Dicts mixed with Arrays

  • The answer at Attempt 3: Just Right (so far) from BlissRage’s answer does not properly handle arrays elements. I’m including a patch in case anyone needs it. The method is handles list with the statement block of if isinstance(v, list):, which scrubs the list using the original scrub_dict(d) implementation.
    @staticmethod
    def scrub_dict(d):
        new_dict = {}
        for k, v in d.items():
            if isinstance(v, dict):
                v = scrub_dict(v)
            if isinstance(v, list):
                v = scrub_list(v)
            if not v in (u'', None, {}):
                new_dict[k] = v
        return new_dict

    @staticmethod
    def scrub_list(d):
        scrubbed_list = []
        for i in d:
            if isinstance(i, dict):
                i = scrub_dict(i)
            scrubbed_list.append(i)
        return scrubbed_list

回答 12

您可以执行此操作的另一种方法是使用字典理解。这应该与2.7+

result = {
    key: value for key, value in
    {"foo": "bar", "lorem": None}.items()
    if value
}

An alternative way you can do this, is using dictionary comprehension. This should be compatible with 2.7+

result = {
    key: value for key, value in
    {"foo": "bar", "lorem": None}.items()
    if value
}

回答 13

如果您使用的是以下选项pandas

import pandas as pd

d = dict.fromkeys(['a', 'b', 'c', 'd'])
d['b'] = 'not null'
d['c'] = ''  # empty string

print(d)

# convert `dict` to `Series` and replace any blank strings with `None`;
# use the `.dropna()` method and
# then convert back to a `dict`
d_ = pd.Series(d).replace('', None).dropna().to_dict()

print(d_)

Here is an option if you are using pandas:

import pandas as pd

d = dict.fromkeys(['a', 'b', 'c', 'd'])
d['b'] = 'not null'
d['c'] = ''  # empty string

print(d)

# convert `dict` to `Series` and replace any blank strings with `None`;
# use the `.dropna()` method and
# then convert back to a `dict`
d_ = pd.Series(d).replace('', None).dropna().to_dict()

print(d_)

回答 14

上面提到的某些方法会忽略是否存在整数,并且会以0和0.0的值进行浮点运算

如果有人想避免上述情况,可以使用以下代码(从嵌套字典和嵌套列表中删除空字符串和None值):

def remove_empty_from_dict(d):
    if type(d) is dict:
        _temp = {}
        for k,v in d.items():
            if v == None or v == "":
                pass
            elif type(v) is int or type(v) is float:
                _temp[k] = remove_empty_from_dict(v)
            elif (v or remove_empty_from_dict(v)):
                _temp[k] = remove_empty_from_dict(v)
        return _temp
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if( (str(v).strip() or str(remove_empty_from_dict(v)).strip()) and (v != None or remove_empty_from_dict(v) != None))]
    else:
        return d

Some of Methods mentioned above ignores if there are any integers and float with values 0 & 0.0

If someone wants to avoid the above can use below code(removes empty strings and None values from nested dictionary and nested list):

def remove_empty_from_dict(d):
    if type(d) is dict:
        _temp = {}
        for k,v in d.items():
            if v == None or v == "":
                pass
            elif type(v) is int or type(v) is float:
                _temp[k] = remove_empty_from_dict(v)
            elif (v or remove_empty_from_dict(v)):
                _temp[k] = remove_empty_from_dict(v)
        return _temp
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if( (str(v).strip() or str(remove_empty_from_dict(v)).strip()) and (v != None or remove_empty_from_dict(v) != None))]
    else:
        return d

回答 15

“由于我目前还为使用Python编写一个桌面应用程序,因此我在数据输入应用程序中发现有很多条目,而其中一些条目不是强制性的,因此用户可以将其留空,以进行验证,因此很容易抓住。所有条目,然后丢弃空键或字典的值,因此我的代码上方显示了如何使用字典理解功能轻松地将它们取出,并保留不为空的字典值元素。我使用Python 3.8.3

data = {'':'', '20':'', '50':'', '100':'1.1', '200':'1.2'}

dic = {key:value for key,value in data.items() if value != ''}

print(dic)

{'100': '1.1', '200': '1.2'}

“As I also currently write a desktop application for my work with Python, I found in data-entry application when there is lots of entry and which some are not mandatory thus user can left it blank, for validation purpose, it is easy to grab all entries and then discard empty key or value of a dictionary. So my code above a show how we can easy take them out, using dictionary comprehension and keep dictionary value element which is not blank. I use Python 3.8.3

data = {'':'', '20':'', '50':'', '100':'1.1', '200':'1.2'}

dic = {key:value for key,value in data.items() if value != ''}

print(dic)

{'100': '1.1', '200': '1.2'}

回答 16

一些基准测试:

1.列表理解重新创建字典

In [7]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None
   ...: dic = {k: v for k, v in dic.items() if v is not None} 
   1000000 loops, best of 7: 375 ns per loop

2.列表理解使用dict()重新创建dict

In [8]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None
   ...: dic = dict((k, v) for k, v in dic.items() if v is not None)
1000000 loops, best of 7: 681 ns per loop

3.如果v为None,则循环并删除密钥

In [10]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None
    ...: for k, v in dic.items():
    ...:   if v is None:
    ...:     del dic[k]
    ...: 
10000000 loops, best of 7: 160 ns per loop

因此循环和删除最快在160ns时完成,列表理解在375ns时慢了一半,而调用dict()则在680ns时又慢了一半。

将3包装到函数中可将其再次降低到约275ns。对我来说,PyPy的速度也快于neet python的两倍。

Some benchmarking:

1. List comprehension recreate dict

In [7]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None
   ...: dic = {k: v for k, v in dic.items() if v is not None} 
   1000000 loops, best of 7: 375 ns per loop

2. List comprehension recreate dict using dict()

In [8]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None
   ...: dic = dict((k, v) for k, v in dic.items() if v is not None)
1000000 loops, best of 7: 681 ns per loop

3. Loop and delete key if v is None

In [10]: %%timeit dic = {str(i):i for i in xrange(10)}; dic['10'] = None; dic['5'] = None
    ...: for k, v in dic.items():
    ...:   if v is None:
    ...:     del dic[k]
    ...: 
10000000 loops, best of 7: 160 ns per loop

so loop and delete is the fastest at 160ns, list comprehension is half as slow at ~375ns and with a call to dict() is half as slow again ~680ns.

Wrapping 3 into a function brings it back down again to about 275ns. Also for me PyPy was about twice as fast as neet python.


[]和{}与list()和dict(),哪个更好?

问题:[]和{}与list()和dict(),哪个更好?

我知道它们本质上是同一件事,但是就样式而言,哪个是创建空列表或字典的更好(更Pythonic的)?

I understand that they are both essentially the same thing, but in terms of style, which is the better (more Pythonic) one to use to create an empty list or dict?


回答 0

在速度方面,空列表/字典没有竞争:

>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077

对于非空:

>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267

另外,使用方括号表示法还可以使您使用列表和字典理解,这可能就足够了。

In terms of speed, it’s no competition for empty lists/dicts:

>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077

and for non-empty:

>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267

Also, using the bracket notation lets you use list and dictionary comprehensions, which may be reason enough.


回答 1

我认为[]并且{}是创建空列表/字典的最Python易懂的方法。

不过请注意set(),例如:

this_set = {5}
some_other_set = {}

可能会造成混乱。第一个创建一个带有一个元素的集合,第二个创建一个空字典而不是一个集合。

In my opinion [] and {} are the most pythonic and readable ways to create empty lists/dicts.

Be wary of set()‘s though, for example:

this_set = {5}
some_other_set = {}

Can be confusing. The first creates a set with one element, the second creates an empty dict and not a set.


回答 2

该字典的文字可能是一个小小的其字节码更短更快一点:

In [1]: import dis
In [2]: a = lambda: {}
In [3]: b = lambda: dict()

In [4]: dis.dis(a)
  1           0 BUILD_MAP                0
              3 RETURN_VALUE

In [5]: dis.dis(b)
  1           0 LOAD_GLOBAL              0 (dict)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE

同样适用于listVS[]

The dict literal might be a tiny bit faster as its bytecode is shorter:

In [1]: import dis
In [2]: a = lambda: {}
In [3]: b = lambda: dict()

In [4]: dis.dis(a)
  1           0 BUILD_MAP                0
              3 RETURN_VALUE

In [5]: dis.dis(b)
  1           0 LOAD_GLOBAL              0 (dict)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE

Same applies to the list vs []


回答 3

恕我直言,使用list()dict()让你的Python看起来像C.唉。

IMHO, using list() and dict() makes your Python look like C. Ugh.


回答 4

对于[]和list()之间的差异,存在一个陷阱,我没有看到其他人指出过。如果将字典用作列表的成员,则两者将给出完全不同的结果:

In [1]: foo_dict = {"1":"foo", "2":"bar"}

In [2]: [foo_dict]
Out [2]: [{'1': 'foo', '2': 'bar'}]

In [3]: list(foo_dict)
Out [3]: ['1', '2'] 

In the case of difference between [] and list(), there is a pitfall that I haven’t seen anyone else point out. If you use a dictionary as a member of the list, the two will give entirely different results:

In [1]: foo_dict = {"1":"foo", "2":"bar"}

In [2]: [foo_dict]
Out [2]: [{'1': 'foo', '2': 'bar'}]

In [3]: list(foo_dict)
Out [3]: ['1', '2'] 

回答 5

list()和[]的工作方式不同:

>>> def a(p=None):
...     print(id(p))
... 
>>> for r in range(3):
...     a([])
... 
139969725291904
139969725291904
139969725291904
>>> for r in range(3):
...     a(list())
... 
139969725367296
139969725367552
139969725367616

list()总是在堆中创建新对象,但是[]可以出于多种原因重用存储单元。

list() and [] work differently:

>>> def a(p):
...     print(id(p))
... 
>>> for r in range(3):
...     a([])
... 
139969725291904
139969725291904
139969725291904
>>> for r in range(3):
...     a(list())
... 
139969725367296
139969725367552
139969725367616

list() always create new object in heap, but [] can reuse memory cell in many reason.


回答 6

如下所示,[]和list()在行为上有一个区别。如果要返回数字列表,则需要使用list(),否则我们将获得一个map对象!不确定如何解释。

sth = [(1,2), (3,4),(5,6)]
sth2 = map(lambda x: x[1], sth) 
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>

sth2 = [map(lambda x: x[1], sth)]
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
type(sth2) # list 
type(sth2[0]) # map

sth2 = list(map(lambda x: x[1], sth))
print(sth2) #[2, 4, 6]
type(sth2) # list
type(sth2[0]) # int

there is one difference in behavior between [] and list() as example below shows. we need to use list() if we want to have the list of numbers returned, otherwise we get a map object! No sure how to explain it though.

sth = [(1,2), (3,4),(5,6)]
sth2 = map(lambda x: x[1], sth) 
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>

sth2 = [map(lambda x: x[1], sth)]
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
type(sth2) # list 
type(sth2[0]) # map

sth2 = list(map(lambda x: x[1], sth))
print(sth2) #[2, 4, 6]
type(sth2) # list
type(sth2[0]) # int

回答 7

方括号对表示列表对象或索引下标my_List [x]中的一个。

大括号对表示字典对象。

a_list = [‘on’,’off’,1,2]

a_dict = {开启:1,关闭:2}

A box bracket pair denotes one of a list object, or an index subscript, my_List[x].

A curly brace pair denotes a dictionary object.

a_list = [‘on’, ‘off’, 1, 2]

a_dict = { on: 1, off: 2 }


回答 8

大多数时候,这主要是选择问题。这是一个偏好问题。

但是请注意,例如,如果您有数字键,则不能这样做:

mydict = dict(1="foo", 2="bar")

你所要做的:

mydict = {"1":"foo", "2":"bar"}

It’s mainly a matter of choice most of the time. It’s a matter of preference.

Note however that if you have numeric keys for example, that you can’t do:

mydict = dict(1="foo", 2="bar")

You have to do:

mydict = {"1":"foo", "2":"bar"}

一个像dict一样的python类

问题:一个像dict一样的python类

我想编写一个行为类似的自定义类dict-因此,我继承自dict

不过,我的问题是:我需要dict在我的__init__()方法中创建一个私有成员吗?我不明白这一点,因为dict如果我仅继承自,我就已经有行为了dict

谁能指出为什么大多数继承片段看起来像下面的片段?

class CustomDictOne(dict):
   def __init__(self):
      self._mydict = {} 

   # other methods follow

而不是简单的…

class CustomDictTwo(dict):
   def __init__(self):
      # initialize my other stuff here ...

   # other methods follow

实际上,我认为我怀疑问题的答案是,用户无法直接访问您的词典(即,他们必须使用您提供的访问方法)。

但是,数组访问运算符[]呢?一个人将如何实现呢?到目前为止,我还没有看到显示如何重写[]运算符的示例。

因此,如果[]在自定义类中未提供访问函数,则继承的基本方法将在其他字典上运行吗?

我尝试了以下代码段来测试我对Python继承的理解:

class myDict(dict):
    def __init__(self):
        self._dict = {}

    def add(self, id, val):
        self._dict[id] = val


md = myDict()
md.add('id', 123)
print md[id]

我收到以下错误:

KeyError:<内置函数ID>

上面的代码有什么问题?

如何更正该类,myDict以便可以编写这样的代码?

md = myDict()
md['id'] = 123

[编辑]

我已经编辑了上面的代码示例,以摆脱在离开办公桌前犯下的愚蠢错误。这是一个错字(我应该从错误消息中发现它)。

I want to write a custom class that behaves like dict – so, I am inheriting from dict.

My question, though, is: Do I need to create a private dict member in my __init__() method?. I don’t see the point of this, since I already have the dict behavior if I simply inherit from dict.

Can anyone point out why most of the inheritance snippets look like the one below?

class CustomDictOne(dict):
   def __init__(self):
      self._mydict = {} 

   # other methods follow

Instead of the simpler…

class CustomDictTwo(dict):
   def __init__(self):
      # initialize my other stuff here ...

   # other methods follow

Actually, I think I suspect the answer to the question is so that users cannot directly access your dictionary (i.e. they have to use the access methods that you have provided).

However, what about the array access operator []? How would one implement that? So far, I have not seen an example that shows how to override the [] operator.

So if a [] access function is not provided in the custom class, the inherited base methods will be operating on a different dictionary?

I tried the following snippet to test out my understanding of Python inheritance:

class myDict(dict):
    def __init__(self):
        self._dict = {}

    def add(self, id, val):
        self._dict[id] = val


md = myDict()
md.add('id', 123)
print md[id]

I got the following error:

KeyError: < built-in function id>

What is wrong with the code above?

How do I correct the class myDict so that I can write code like this?

md = myDict()
md['id'] = 123

[Edit]

I have edited the code sample above to get rid of the silly error I made before I dashed away from my desk. It was a typo (I should have spotted it from the error message).


回答 0

查看有关模拟容器类型的文档。您的情况下,第一个参数add应为self

Check the documentation on emulating container types. In your case, the first parameter to add should be self.


回答 1

class Mapping(dict):

    def __setitem__(self, key, item):
        self.__dict__[key] = item

    def __getitem__(self, key):
        return self.__dict__[key]

    def __repr__(self):
        return repr(self.__dict__)

    def __len__(self):
        return len(self.__dict__)

    def __delitem__(self, key):
        del self.__dict__[key]

    def clear(self):
        return self.__dict__.clear()

    def copy(self):
        return self.__dict__.copy()

    def has_key(self, k):
        return k in self.__dict__

    def update(self, *args, **kwargs):
        return self.__dict__.update(*args, **kwargs)

    def keys(self):
        return self.__dict__.keys()

    def values(self):
        return self.__dict__.values()

    def items(self):
        return self.__dict__.items()

    def pop(self, *args):
        return self.__dict__.pop(*args)

    def __cmp__(self, dict_):
        return self.__cmp__(self.__dict__, dict_)

    def __contains__(self, item):
        return item in self.__dict__

    def __iter__(self):
        return iter(self.__dict__)

    def __unicode__(self):
        return unicode(repr(self.__dict__))


o = Mapping()
o.foo = "bar"
o['lumberjack'] = 'foo'
o.update({'a': 'b'}, c=44)
print 'lumberjack' in o
print o

In [187]: run mapping.py
True
{'a': 'b', 'lumberjack': 'foo', 'foo': 'bar', 'c': 44}
class Mapping(dict):

    def __setitem__(self, key, item):
        self.__dict__[key] = item

    def __getitem__(self, key):
        return self.__dict__[key]

    def __repr__(self):
        return repr(self.__dict__)

    def __len__(self):
        return len(self.__dict__)

    def __delitem__(self, key):
        del self.__dict__[key]

    def clear(self):
        return self.__dict__.clear()

    def copy(self):
        return self.__dict__.copy()

    def has_key(self, k):
        return k in self.__dict__

    def update(self, *args, **kwargs):
        return self.__dict__.update(*args, **kwargs)

    def keys(self):
        return self.__dict__.keys()

    def values(self):
        return self.__dict__.values()

    def items(self):
        return self.__dict__.items()

    def pop(self, *args):
        return self.__dict__.pop(*args)

    def __cmp__(self, dict_):
        return self.__cmp__(self.__dict__, dict_)

    def __contains__(self, item):
        return item in self.__dict__

    def __iter__(self):
        return iter(self.__dict__)

    def __unicode__(self):
        return unicode(repr(self.__dict__))


o = Mapping()
o.foo = "bar"
o['lumberjack'] = 'foo'
o.update({'a': 'b'}, c=44)
print 'lumberjack' in o
print o

In [187]: run mapping.py
True
{'a': 'b', 'lumberjack': 'foo', 'foo': 'bar', 'c': 44}

回答 2

像这样

class CustomDictOne(dict):
   def __init__(self,*arg,**kw):
      super(CustomDictOne, self).__init__(*arg, **kw)

现在你可以使用内置的功能,如dict.get()作为self.get()

您无需包装隐藏的self._dict。您的类已经字典。

Like this

class CustomDictOne(dict):
   def __init__(self,*arg,**kw):
      super(CustomDictOne, self).__init__(*arg, **kw)

Now you can use the built-in functions, like dict.get() as self.get().

You do not need to wrap a hidden self._dict. Your class already is a dict.


回答 3

为了完整起见,这里是@björn-pollex提到的有关最新Python 2.x(截至撰写本文时为2.7.7)的文档的链接:

模拟容器类型

(很抱歉,您未使用注释功能,但是stackoverflow不允许这样做。)

For the sake of completeness, here is the link to the documentation mentioned by @björn-pollex for the latest Python 2.x (2.7.7 as of the time of writing):

Emulating Container Types

(Sorry for not using the comments function, I’m just not allowed to do so by stackoverflow.)


回答 4

此代码段的问题:

class myDict(dict):
    def __init__(self):
        self._dict = {}

    def add(id, val):
        self._dict[id] = val


md = myDict()
md.add('id', 123)

…是您的’add’方法(…以及您想成为类成员的任何方法)需要声明一个明确的’self’作为其第一个参数,例如:

def add(self, 'id', 23):

要实现操作符重载以按键访问项目,请在文档中查找magic方法__getitem____setitem__

请注意,由于Python使用Duck Typing,因此实际上可能没有理由从语言的dict类派生自定义dict类-无需更多了解您要执行的操作(例如,如果需要传递此方法的实例)类插入某个可能会中断的代码(除非isinstance(MyDict(), dict) == True),您最好实现一个使类足够像字典的API,然后停在那里。

The problem with this chunk of code:

class myDict(dict):
    def __init__(self):
        self._dict = {}

    def add(id, val):
        self._dict[id] = val


md = myDict()
md.add('id', 123)

…is that your ‘add’ method (…and any method you want to be a member of a class) needs to have an explicit ‘self’ declared as its first argument, like:

def add(self, 'id', 23):

To implement the operator overloading to access items by key, look in the docs for the magic methods __getitem__ and __setitem__.

Note that because Python uses Duck Typing, there may actually be no reason to derive your custom dict class from the language’s dict class — without knowing more about what you’re trying to do (e.g, if you need to pass an instance of this class into some code someplace that will break unless isinstance(MyDict(), dict) == True), you may be better off just implementing the API that makes your class sufficiently dict-like and stopping there.


回答 5

这是一个替代解决方案:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__dict__ = self

a = AttrDict()
a.a = 1
a.b = 2

Here is an alternative solution:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__dict__ = self

a = AttrDict()
a.a = 1
a.b = 2

回答 6

我真的在任何地方都看不到正确的答案

class MyClass(dict):
    
    def __init__(self, a_property):
        self[a_property] = a_property

您真正要做的就是定义自己的__init__-确实就是它的全部。

另一个例子(稍微复杂一点):

class MyClass(dict):

    def __init__(self, planet):
        self[planet] = planet
        info = self.do_something_that_returns_a_dict()
        if info:
            for k, v in info.items():
                self[k] = v

    def do_something_that_returns_a_dict(self):
        return {"mercury": "venus", "mars": "jupiter"}

当您想嵌入某种逻辑时,这最后一个例子很方便。

总之……简而言之class GiveYourClassAName(dict),足以使您的课堂像字典一样行事。您执行的任何dict操作都self将像常规dict。

I really don’t see the right answer to this anywhere

class MyClass(dict):
    
    def __init__(self, a_property):
        self[a_property] = a_property

All you are really having to do is define your own __init__ – that really is all that there is too it.

Another example (little more complex):

class MyClass(dict):

    def __init__(self, planet):
        self[planet] = planet
        info = self.do_something_that_returns_a_dict()
        if info:
            for k, v in info.items():
                self[k] = v

    def do_something_that_returns_a_dict(self):
        return {"mercury": "venus", "mars": "jupiter"}

This last example is handy when you want to embed some kind of logic.

Anyway… in short class GiveYourClassAName(dict) is enough to make your class act like a dict. Any dict operation you do on self will be just like a regular dict.


回答 7

这是我最好的解决方案。我使用了很多次。

class DictLikeClass:
    ...
    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        setattr(self, key, value)
    ...

您可以这样使用:

>>> d = DictLikeClass()
>>> d["key"] = "value"
>>> print(d["key"])

This is my best solution. I used this many times.

class DictLikeClass:
    ...
    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        setattr(self, key, value)
    ...

You can use like:

>>> d = DictLikeClass()
>>> d["key"] = "value"
>>> print(d["key"])

回答 8

永远不要继承自Python内置字典!例如update方法woldn’t use __setitem__,他们做了很多优化工作。使用UserDict。

from collections import UserDict

class MyDict(UserDict):
    def __delitem__(self, key):
        pass
    def __setitem__(self, key, value):
        pass

Don’t inherit from Python built-in dict, ever! for example update method woldn’t use __setitem__, they do a lot for optimization. Use UserDict.

from collections import UserDict

class MyDict(UserDict):
    def __delitem__(self, key):
        pass
    def __setitem__(self, key, value):
        pass

当关键字不明时从字典中删除项目

问题:当关键字不明时从字典中删除项目

按值从字典中删除某项的最佳方法是什么,即当该项的键未知时?这是一个简单的方法:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

有更好的方法吗?迭代字典时从字典中进行变异(删除项目)有什么问题吗?

What is the best way to remove an item from a dictionary by value, i.e. when the item’s key is unknown? Here’s a simple approach:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

Are there better ways? Is there anything wrong with mutating (deleting items) from the dictionary while iterating it?


回答 0

请注意,您当前正在测试对象的身份(isTrue当两个操作数由内存中的同一对象表示时才返回-与相等的两个对象并不总是这样==)。如果您故意这样做,则可以将代码重写为

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}

但这可能无法满足您的要求:

>>> some_dict = {1: "Hello", 2: "Goodbye", 3: "You say yes", 4: "I say no"}
>>> value_to_remove = "You say yes"
>>> some_dict = {key: value for key, value in some_dict.items() if value is not value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 3: 'You say yes', 4: 'I say no'}
>>> some_dict = {key: value for key, value in some_dict.items() if value != value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 4: 'I say no'}

所以您可能想要!=代替is not

Be aware that you’re currently testing for object identity (is only returns True if both operands are represented by the same object in memory – this is not always the case with two object that compare equal with ==). If you are doing this on purpose, then you could rewrite your code as

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}

But this may not do what you want:

>>> some_dict = {1: "Hello", 2: "Goodbye", 3: "You say yes", 4: "I say no"}
>>> value_to_remove = "You say yes"
>>> some_dict = {key: value for key, value in some_dict.items() if value is not value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 3: 'You say yes', 4: 'I say no'}
>>> some_dict = {key: value for key, value in some_dict.items() if value != value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 4: 'I say no'}

So you probably want != instead of is not.


回答 1

dict.pop(key[, default])方法允许您在知道密钥时删除项目。如果删除该项目,则返回键处的值,否则返回传递为的值default。查看文档

例:

>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}

The dict.pop(key[, default]) method allows you to remove items when you know the key. It returns the value at the key if it removes the item otherwise it returns what is passed as default. See the docs.’

Example:

>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}

回答 2

a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']
a = {'name': 'your_name','class': 4}
if 'name' in a: del a['name']

回答 3

delpop()之间的简单比较:

import timeit
code = """
results = {'A': 1, 'B': 2, 'C': 3}
del results['A']
del results['B']
"""
print timeit.timeit(code, number=100000)
code = """
results = {'A': 1, 'B': 2, 'C': 3}
results.pop('A')
results.pop('B')
"""
print timeit.timeit(code, number=100000)

结果:

0.0329667857143
0.0451040902256

因此,delpop()快。

A simple comparison between del and pop():

import timeit
code = """
results = {'A': 1, 'B': 2, 'C': 3}
del results['A']
del results['B']
"""
print timeit.timeit(code, number=100000)
code = """
results = {'A': 1, 'B': 2, 'C': 3}
results.pop('A')
results.pop('B')
"""
print timeit.timeit(code, number=100000)

result:

0.0329667857143
0.0451040902256

So, del is faster than pop().


回答 4

items()返回一个列表,而该列表正是您要迭代的列表,因此在此循环中更改dict并不重要。如果您使用的是iteritems()替代方法,则在循环中更改dict 是有问题的viewitems()在Python 2.7中同样如此。

我想不出一种更好的方法来按值从字典中删除项目。

items() returns a list, and it is that list you are iterating, so mutating the dict in the loop doesn’t matter here. If you were using iteritems() instead, mutating the dict in the loop would be problematic, and likewise for viewitems() in Python 2.7.

I can’t think of a better way to remove items from a dict by value.


回答 5

我将建立一个需要删除的密钥列表,然后将其删除。它简单,高效,并且避免了同时迭代和变异字典的任何问题。

keys_to_remove = [key for key, value in some_dict.iteritems()
                  if value == value_to_remove]
for key in keys_to_remove:
    del some_dict[key]

I’d build a list of keys that need removing, then remove them. It’s simple, efficient and avoids any problem about simultaneously iterating over and mutating the dict.

keys_to_remove = [key for key, value in some_dict.iteritems()
                  if value == value_to_remove]
for key in keys_to_remove:
    del some_dict[key]

回答 6

c是新字典,a是您的原始字典,{‘z’,’w’}是您要从a中删除的键

c = {key:a[key] for key in a.keys() - {'z', 'w'}}

另请检查:https : //www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch01.html

c is the new dictionary, and a is your original dictionary, {‘z’,’w’} are the keys you want to remove from a

c = {key:a[key] for key in a.keys() - {'z', 'w'}}

Also check: https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch01.html


回答 7

y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]
y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]

回答 8

正如您所建议的,在迭代时从字典中删除项目没有任何问题。注意多个线程同时使用同一字典,这可能会导致KeyError或其他问题。

当然,请参阅http://docs.python.org/library/stdtypes.html#typesmapping中的文档

There is nothing wrong with deleting items from the dictionary while iterating, as you’ve proposed. Be careful about multiple threads using the same dictionary at the same time, which may result in a KeyError or other problems.

Of course, see the docs at http://docs.python.org/library/stdtypes.html#typesmapping


回答 9

这就是我要做的。

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break

This is how I would do it.

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break

字典元组列表

问题:字典元组列表

这是我目前在Python中将元组列表转换为字典的方式:

l = [('a',1),('b',2)]
h = {}
[h.update({k:v}) for k,v in l]
> [None, None]
h
> {'a': 1, 'b': 2}

有没有更好的办法?似乎应该有一种做法。

Here’s how I’m currently converting a list of tuples to dictionary in Python:

l = [('a',1),('b',2)]
h = {}
[h.update({k:v}) for k,v in l]
> [None, None]
h
> {'a': 1, 'b': 2}

Is there a better way? It seems like there should be a one-liner to do this.


回答 0

只需dict()直接调用元组列表

>>> my_list = [('a', 1), ('b', 2)]
>>> dict(my_list)
{'a': 1, 'b': 2}

Just call dict() on the list of tuples directly

>>> my_list = [('a', 1), ('b', 2)]
>>> dict(my_list)
{'a': 1, 'b': 2}

回答 1

dict构造函数接受输入的完全一样,你把它(键/值元组)。

>>> l = [('a',1),('b',2)]
>>> d = dict(l)
>>> d
{'a': 1, 'b': 2}

文档中

例如,所有这些都返回等于{“ one”:1,“ two”:2}的字典:

dict(one=1, two=2)
dict({'one': 1, 'two': 2})
dict(zip(('one', 'two'), (1, 2)))
dict([['two', 2], ['one', 1]])

The dict constructor accepts input exactly as you have it (key/value tuples).

>>> l = [('a',1),('b',2)]
>>> d = dict(l)
>>> d
{'a': 1, 'b': 2}

From the documentation:

For example, these all return a dictionary equal to {“one”: 1, “two”: 2}:

dict(one=1, two=2)
dict({'one': 1, 'two': 2})
dict(zip(('one', 'two'), (1, 2)))
dict([['two', 2], ['one', 1]])

回答 2

具有dict理解力:

h = {k:v for k,v in l}

With dict comprehension:

h = {k:v for k,v in l}

回答 3

似乎每个人都假定元组列表在键和值之间具有一对一的映射关系(例如,它没有字典的重复键)。由于这是在该主题上搜索的第一个问题,因此我针对一个更常见的情况发布了答案,在这种情况下,我们必须处理重复项:

mylist = [(a,1),(a,2),(b,3)]    
result = {}
for i in mylist:  
   result.setdefault(i[0],[]).append(i[1])
print(result)
>>> result = {a:[1,2], b:[3]}

It seems everyone here assumes the list of tuples have one to one mapping between key and values (e.g. it does not have duplicated keys for the dictionary). As this is the first question coming up searching on this topic, I post an answer for a more general case where we have to deal with duplicates:

mylist = [(a,1),(a,2),(b,3)]    
result = {}
for i in mylist:  
   result.setdefault(i[0],[]).append(i[1])
print(result)
>>> result = {a:[1,2], b:[3]}

python pandas dataframe列转换为dict键和值

问题:python pandas dataframe列转换为dict键和值

我有一个带有多列的pandas数据框,我想从两列构造一个dict:一个作为dict的键,另一个作为dict的值。我怎样才能做到这一点?

数据框:

           area  count
co tp
DE Lake      10      7
Forest       20      5
FR Lake      30      2
Forest       40      3

我需要将区域定义为键,在dict中计为值。先感谢您。

I have a pandas data frame with multiple columns and I would like to construct a dict from two columns: one as the dict’s keys and the other as the dict’s values. How can I do that?

Dataframe:

           area  count
co tp
DE Lake      10      7
Forest       20      5
FR Lake      30      2
Forest       40      3

I need to define area as key, count as value in dict. Thank you in advance.


回答 0

如果lakes是您DataFrame,则可以执行以下操作

area_dict = dict(zip(lakes.area, lakes.count))

If lakes is your DataFrame, you can do something like

area_dict = dict(zip(lakes.area, lakes.count))

回答 1

使用大熊猫可以做到:

如果lakes是您的DataFrame:

area_dict = lakes.to_dict('records')

With pandas it can be done as:

If lakes is your DataFrame:

area_dict = lakes.to_dict('records')

回答 2

如果您想和熊猫玩耍,也可以这样做。但是,我喜欢punchagan的方式。

# replicating your dataframe
lake = pd.DataFrame({'co tp': ['DE Lake', 'Forest', 'FR Lake', 'Forest'], 
                 'area': [10, 20, 30, 40], 
                 'count': [7, 5, 2, 3]})
lake.set_index('co tp', inplace=True)

# to get key value using pandas
area_dict = lake.set_index('area').T.to_dict('records')[0]
print(area_dict)

output: {10: 7, 20: 5, 30: 2, 40: 3}

You can also do this if you want to play around with pandas. However, I like punchagan’s way.

# replicating your dataframe
lake = pd.DataFrame({'co tp': ['DE Lake', 'Forest', 'FR Lake', 'Forest'], 
                 'area': [10, 20, 30, 40], 
                 'count': [7, 5, 2, 3]})
lake.set_index('co tp', inplace=True)

# to get key value using pandas
area_dict = lake.set_index('area').T.to_dict('records')[0]
print(area_dict)

output: {10: 7, 20: 5, 30: 2, 40: 3}

如何与字典中的值交换键?

问题:如何与字典中的值交换键?

我收到一个字典作为输入,并想返回一个字典,其键将是输入的值,而键的值将是对应的输入键。价值观是独一无二的。

例如,说我的输入是:

a = dict()
a['one']=1
a['two']=2

我希望我的输出是:

{1: 'one', 2: 'two'}

为了澄清,我希望我的结果等于以下内容:

res = dict()
res[1] = 'one'
res[2] = 'two'

有什么精巧的Pythonic方式可以做到这一点?

I receive a dictionary as input, and would like to to return a dictionary whose keys will be the input’s values and whose value will be the corresponding input keys. Values are unique.

For example, say my input is:

a = dict()
a['one']=1
a['two']=2

I would like my output to be:

{1: 'one', 2: 'two'}

To clarify I would like my result to be the equivalent of the following:

res = dict()
res[1] = 'one'
res[2] = 'two'

Any neat Pythonic way to achieve this?


回答 0

Python 2:

res = dict((v,k) for k,v in a.iteritems())

Python 3(感谢@erik):

res = dict((v,k) for k,v in a.items())

Python 2:

res = dict((v,k) for k,v in a.iteritems())

Python 3 (thanks to @erik):

res = dict((v,k) for k,v in a.items())

回答 1

new_dict = dict(zip(my_dict.values(), my_dict.keys()))
new_dict = dict(zip(my_dict.values(), my_dict.keys()))

回答 2

从Python 2.7起,包括3.0及更高版本,有一个更短,更易读的版本:

>>> my_dict = {'x':1, 'y':2, 'z':3}
>>> {v: k for k, v in my_dict.items()}
{1: 'x', 2: 'y', 3: 'z'}

From Python 2.7 on, including 3.0+, there’s an arguably shorter, more readable version:

>>> my_dict = {'x':1, 'y':2, 'z':3}
>>> {v: k for k, v in my_dict.items()}
{1: 'x', 2: 'y', 3: 'z'}

回答 3

In [1]: my_dict = {'x':1, 'y':2, 'z':3}

In [2]: dict((value, key) for key, value in my_dict.iteritems())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}
In [1]: my_dict = {'x':1, 'y':2, 'z':3}

In [2]: dict((value, key) for key, value in my_dict.iteritems())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}

回答 4

您可以利用dict理解

res = {v: k for k, v in a.iteritems()}

编辑:对于Python 3,请使用a.items()代替a.iteritems()。可以在Python on SO的迭代项目中找到有关它们之间差异的讨论。

You can make use of dict comprehensions:

res = {v: k for k, v in a.iteritems()}

Edited: For Python 3, use a.items() instead of a.iteritems(). Discussions about the differences between them can be found in iteritems in Python on SO.


回答 5

您可以尝试:

d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.iteritems())
d2
  {'two': 2, 'one': 1}

注意,如果出现以下情况,您将无法“撤消”字典

  1. 多个密钥共享相同的值。例如{'one':1,'two':1}。新字典只能有一个带有key的项目1
  2. 一个或多个值是不可散列的。例如{'one':[1]}[1]是有效值,但不是有效键。

有关此主题的讨论,请参见python邮件列表上的该线程

You could try:

d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.iteritems())
d2
  {'two': 2, 'one': 1}

Beware that you cannot ‘reverse’ a dictionary if

  1. More than one key shares the same value. For example {'one':1,'two':1}. The new dictionary can only have one item with key 1.
  2. One or more of the values is unhashable. For example {'one':[1]}. [1] is a valid value but not a valid key.

See this thread on the python mailing list for a discussion on the subject.


回答 6

res = dict(zip(a.values(), a.keys()))

res = dict(zip(a.values(), a.keys()))


回答 7

当前的主要答案假设值是唯一的,但并非总是如此。如果值不是唯一的怎么办?您将失去信息!例如:

d = {'a':3, 'b': 2, 'c': 2} 
{v:k for k,v in d.iteritems()} 

返回{2: 'b', 3: 'a'}

有关的信息'c'被完全忽略。理想情况下应该是这样的{2: ['b','c'], 3: ['a']}。这就是最底层的实现。

Python 2.x

def reverse_non_unique_mapping(d):
    dinv = {}
    for k, v in d.iteritems():
        if v in dinv:
            dinv[v].append(k)
        else:
            dinv[v] = [k]
    return dinv

Python 3.x

def reverse_non_unique_mapping(d):
    dinv = {}
    for k, v in d.items():
        if v in dinv:
            dinv[v].append(k)
        else:
            dinv[v] = [k]
    return dinv

The current leading answer assumes values are unique which is not always the case. What if values are not unique? You will loose information! For example:

d = {'a':3, 'b': 2, 'c': 2} 
{v:k for k,v in d.iteritems()} 

returns {2: 'b', 3: 'a'}.

The information about 'c' was completely ignored. Ideally it should had be something like {2: ['b','c'], 3: ['a']}. This is what the bottom implementation does.

Python 2.x

def reverse_non_unique_mapping(d):
    dinv = {}
    for k, v in d.iteritems():
        if v in dinv:
            dinv[v].append(k)
        else:
            dinv[v] = [k]
    return dinv

Python 3.x

def reverse_non_unique_mapping(d):
    dinv = {}
    for k, v in d.items():
        if v in dinv:
            dinv[v].append(k)
        else:
            dinv[v] = [k]
    return dinv

回答 8

new_dict = dict( (my_dict[k], k) for k in my_dict)

甚至更好,但仅适用于Python 3:

new_dict = { my_dict[k]: k for k in my_dict}
new_dict = dict( (my_dict[k], k) for k in my_dict)

or even better, but only works in Python 3:

new_dict = { my_dict[k]: k for k in my_dict}

回答 9

扩展Ilya Prokin响应的另一种方法是实际使用该reversed功能。

dict(map(reversed, my_dict.items()))

本质上,您的字典通过(使用.items())进行迭代,其中每个项目都是键/值对,并且这些项目与reversed函数交换。当将其传递给dict构造函数时,它将把它们变成您想要的值/键对。

Another way to expand on Ilya Prokin‘s response is to actually use the reversed function.

dict(map(reversed, my_dict.items()))

In essence, your dictionary is iterated through (using .items()) where each item is a key/value pair, and those items are swapped with the reversed function. When this is passed to the dict constructor, it turns them into value/key pairs which is what you want.


回答 10

改善哈维尔答案的建议:

dict(zip(d.values(),d))

而不是d.keys()您只能编写d,因为如果您使用迭代器浏览字典,它将返回相关字典的键。

例如 对于这种行为:

d = {'a':1,'b':2}
for k in d:
 k
'a'
'b'

Suggestion for an improvement for Javier answer :

dict(zip(d.values(),d))

Instead of d.keys() you can write just d, because if you go through dictionary with an iterator, it will return the keys of the relevant dictionary.

Ex. for this behavior :

d = {'a':1,'b':2}
for k in d:
 k
'a'
'b'

回答 11

使用字典理解可以轻松完成:

{d[i]:i for i in d}

Can be done easily with dictionary comprehension:

{d[i]:i for i in d}

回答 12

dict(map(lambda x: x[::-1], YourDict.items()))

.items()返回的元组列表(key, value)map()遍历列表中的元素并应用于lambda x:[::-1]其每个元素(元组)以将其反转,因此每个元组都将(value, key)在新列表中分散在地图之外。最后,dict()从新列表中做出决定。

dict(map(lambda x: x[::-1], YourDict.items()))

.items() returns a list of tuples of (key, value). map() goes through elements of the list and applies lambda x:[::-1] to each its element (tuple) to reverse it, so each tuple becomes (value, key) in the new list spitted out of map. Finally, dict() makes a dict from the new list.


回答 13

使用循环:-

newdict = {} #Will contain reversed key:value pairs.

for key, value in zip(my_dict.keys(), my_dict.values()):
    # Operations on key/value can also be performed.
    newdict[value] = key

Using loop:-

newdict = {} #Will contain reversed key:value pairs.

for key, value in zip(my_dict.keys(), my_dict.values()):
    # Operations on key/value can also be performed.
    newdict[value] = key

回答 14

如果您使用的是Python3,则略有不同:

res = dict((v,k) for k,v in a.items())

If you’re using Python3, it’s slightly different:

res = dict((v,k) for k,v in a.items())

回答 15

添加就地解决方案:

>>> d = {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> for k in list(d.keys()):
...     d[d.pop(k)] = k
... 
>>> d
{'two': 2, 'one': 1, 'four': 4, 'three': 3}

在Python3中,使用它至关重要,list(d.keys())因为它会dict.keys返回键的视图。如果您使用的是Python2,d.keys()就足够了。

Adding an in-place solution:

>>> d = {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> for k in list(d.keys()):
...     d[d.pop(k)] = k
... 
>>> d
{'two': 2, 'one': 1, 'four': 4, 'three': 3}

In Python3, it is critical that you use list(d.keys()) because dict.keys returns a view of the keys. If you are using Python2, d.keys() is enough.


回答 16

Hanan的答案是正确的,因为它涵盖了更一般的情况(其他答案对于没有意识到重复情况的人来说是一种误导)。对Hanan答案的一种改进是使用setdefault:

mydict = {1:a, 2:a, 3:b}   
result = {}
for i in mydict:  
   result.setdefault(mydict[i],[]).append(i)
print(result)
>>> result = {a:[1,2], b:[3]}

Hanan’s answer is the correct one as it covers more general case (the other answers are kind of misleading for someone unaware of the duplicate situation). An improvement to Hanan’s answer is using setdefault:

mydict = {1:a, 2:a, 3:b}   
result = {}
for i in mydict:  
   result.setdefault(mydict[i],[]).append(i)
print(result)
>>> result = {a:[1,2], b:[3]}

如何索引字典?

问题:如何索引字典?

我在下面有一个字典:

colors = {
    "blue" : "5",
    "red" : "6",
    "yellow" : "8",
}

如何索引字典中的第一个条目?

colors[0]KeyError由于明显的原因将返回。

I have a Dictionary below:

colors = {
    "blue" : "5",
    "red" : "6",
    "yellow" : "8",
}

How do I index the first entry in the dictionary?

colors[0] will return a KeyError for obvious reasons.


回答 0

在Python版本(包括Python 3.6)及更高版本中,字典是无序的。如果您不关心条目的顺序,并且仍然想通过索引访问键或值,则可以使用d.keys()[i]d.values()[i]d.items()[i]。(请注意,这些方法创建了Python 2.x中所有键,值或项的列表。因此,如果一次又一次需要它们,请将列表存储在变量中以提高性能。)

如果您确实关心条目的顺序,那么可以从Python 2.7开始使用collections.OrderedDict。或使用成对清单

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

如果您不需要通过密钥访问。(为什么您的数字是字符串?)

在Python 3.7中,常规字典是有序的,因此您不再需要使用它OrderedDict(但您仍然可以使用-它基本上是相同的类型)。Python 3.6的CPython实现已经包含了这一更改,但是由于它不是语言规范的一部分,因此您不能在Python 3.6中依赖它。

Dictionaries are unordered in Python versions up to and including Python 3.6. If you do not care about the order of the entries and want to access the keys or values by index anyway, you can use d.keys()[i] and d.values()[i] or d.items()[i]. (Note that these methods create a list of all keys, values or items in Python 2.x. So if you need them more then once, store the list in a variable to improve performance.)

If you do care about the order of the entries, starting with Python 2.7 you can use collections.OrderedDict. Or use a list of pairs

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

if you don’t need access by key. (Why are your numbers strings by the way?)

In Python 3.7, normal dictionaries are ordered, so you don’t need to use OrderedDict anymore (but you still can – it’s basically the same type). The CPython implementation of Python 3.6 already included that change, but since it’s not part of the language specification, you can’t rely on it in Python 3.6.


回答 1

如果仍然有人在看这个问题,那么当前接受的答案现在已经过时了:

由于Python 3.7 *字典是顺序保留的,也就是说它们现在的行为与collections.OrderedDicts完全相同。不幸的是,仍然没有专用的方法可以索引到字典的keys()/values()中,因此可以通过以下方法获取字典中的第一个键/值:

first_key = list(colors)[0]
first_val = list(colors.values())[0]

或者(避免将键视图实例化为列表):

def get_first_key(dictionary):
    for key in dictionary:
        return key
    raise IndexError

first_key = get_first_key(colors)
first_val = colors[first_key]

如果您需要n-th键,则类似

def get_nth_key(dictionary, n=0):
    if n < 0:
        n += len(dictionary)
    for i, key in enumerate(dictionary.keys()):
        if i == n:
            return key
    raise IndexError("dictionary index out of range") 

(* CPython 3.6已经包含有序字典,但这只是实现细节。语言规范包括3.7以后的有序字典。)

If anybody still looking at this question, the currently accepted answer is now outdated:

Since Python 3.7* the dictionaries are order-preserving, that is they now behave exactly as collections.OrderedDicts used to. Unfortunately, there is still no dedicated method to index into keys() / values() of the dictionary, so getting the first key / value in the dictionary can be done as

first_key = list(colors)[0]
first_val = list(colors.values())[0]

or alternatively (this avoids instantiating the keys view into a list):

def get_first_key(dictionary):
    for key in dictionary:
        return key
    raise IndexError

first_key = get_first_key(colors)
first_val = colors[first_key]

If you need an n-th key, then similarly

def get_nth_key(dictionary, n=0):
    if n < 0:
        n += len(dictionary)
    for i, key in enumerate(dictionary.keys()):
        if i == n:
            return key
    raise IndexError("dictionary index out of range") 

(*CPython 3.6 already included ordered dicts, but this was only an implementation detail. The language specification includes ordered dicts from 3.7 onwards.)


回答 2

处理字典中的元素就像坐在驴上,享受旅程。

作为Python的规则,字典是无序的

如果有

dic = {1: "a", 2: "aa", 3: "aaa"}

现在假设如果我喜欢dic[10] = "b",那么它不会总是这样添加

dic = {1:"a",2:"aa",3:"aaa",10:"b"}

可能像

dic = {1: "a", 2: "aa", 3: "aaa", 10: "b"}

要么

dic = {1: "a", 2: "aa", 10: "b", 3: "aaa"}

要么

dic = {1: "a", 10: "b", 2: "aa", 3: "aaa"}

或任何此类组合。

所以经验法则是字典无序的

Addressing an element of dictionary is like sitting on donkey and enjoy the ride.

As rule of Python DICTIONARY is orderless

If there is

dic = {1: "a", 2: "aa", 3: "aaa"}

Now suppose if I go like dic[10] = "b", then it will not add like this always

dic = {1:"a",2:"aa",3:"aaa",10:"b"}

It may be like

dic = {1: "a", 2: "aa", 3: "aaa", 10: "b"}

Or

dic = {1: "a", 2: "aa", 10: "b", 3: "aaa"}

Or

dic = {1: "a", 10: "b", 2: "aa", 3: "aaa"}

Or any such combination.

So thumb rule is DICTIONARY is orderless!


回答 3

如果需要有序字典,可以使用odict

If you need an ordered dictionary, you can use odict.


回答 4

实际上,我找到了一个新颖的解决方案,确实帮了我大忙,如果您特别关心列表或数据集中某个值的索引,则可以将dictionary的值设置为该Index !:

只是看:

list = ['a', 'b', 'c']
dictionary = {}
counter = 0
for i in list:
   dictionary[i] = counter
   counter += 1

print(dictionary) # dictionary = {'a':0, 'b':1, 'c':2}

现在,借助哈希图的强大功能,您可以在恒定时间内(也就是快得多)拉入条目的索引

actually I found a novel solution that really helped me out, If you are especially concerned with the index of a certain value in a list or data set, you can just set the value of dictionary to that Index!:

Just watch:

list = ['a', 'b', 'c']
dictionary = {}
counter = 0
for i in list:
   dictionary[i] = counter
   counter += 1

print(dictionary) # dictionary = {'a':0, 'b':1, 'c':2}

Now through the power of hashmaps you can pull the index your entries in constant time (aka a whole lot faster)


回答 5

哦,那是一个艰难的过程。基本上,这里的每个项目都有两个值。然后,您尝试使用数字作为键来呼叫他们。不幸的是,您的值之一已经设置为键!

试试这个:

colors = {1: ["blue", "5"], 2: ["red", "6"], 3: ["yellow", "8"]}

现在,您可以按数字调用键,就像它们像列表一样被索引。您还可以通过颜色和数字在列表中的位置进行引用。

例如,

colors[1][0]
// returns 'blue'

colors[3][1]
// returns '8'

当然,您将不得不想出另一种方式来跟踪每种颜色的位置。也许您可以拥有另一本字典来存储每种颜色的键值。

colors_key = {‘蓝色’:1,’红色’:6,’yllow’:8}

然后,您也可以根据需要查找颜色键。

colors [colors_key [‘blue’]] [0]将返回’blue’

这样的事情。

然后,当您使用它时,可以使用数字值作为键进行字典操作,以便始终可以使用它们来查找颜色(如果需要)。

值= {5:[1,’蓝色’],6:[2,’红色’],8:[3,’黄色’]}

然后,(colors [colors_key [values [5] [1]]] [0])将返回’blue’。

或者,您可以使用列表列表。

祝好运!

oh, that’s a tough one. What you have here, basically, is two values for each item. Then you are trying to call them with a number as the key. Unfortunately, one of your values is already set as the key!

Try this:

colors = {1: ["blue", "5"], 2: ["red", "6"], 3: ["yellow", "8"]}

Now you can call the keys by number as if they are indexed like a list. You can also reference the color and number by their position within the list.

For example,

colors[1][0]
// returns 'blue'

colors[3][1]
// returns '8'

Of course, you will have to come up with another way of keeping track of what location each color is in. Maybe you can have another dictionary that stores each color’s key as it’s value.

colors_key = {‘blue’: 1, ‘red’: 6, ‘yllow’: 8}

Then, you will be able to also look up the colors key if you need to.

colors[colors_key[‘blue’]][0] will return ‘blue’

Something like that.

And then, while you’re at it, you can make a dict with the number values as keys so that you can always use them to look up your colors, you know, if you need.

values = {5: [1, ‘blue’], 6: [2, ‘red’], 8: [3, ‘yellow’]}

Then, (colors[colors_key[values[5][1]]][0]) will return ‘blue’.

Or you could use a list of lists.

Good luck!


回答 6

您不能,因为它dict是无序的。您可以.popitem()用来获取任意项,但这会将其从dict中删除。

You can’t, since dict is unordered. you can use .popitem() to get an arbitrary item, but that will remove it from the dict.