简体   繁体   English

Python字典打印首次出现

[英]Python Dictionary Print First occurence

In Python, I currently have a dictionary (it has a composite key from a list within a list) that looks similar to the following when I print it: 在Python中,我目前有一个字典(它有一个列表中列表的复合键),当我打印它时,它看起来类似于以下内容:

the first value is a number, the second value (A or B) refers to a text value and the numbers are a count of the times they appear in the original list of list that this dictionary was derived from. 第一个值是数字,第二个值(A或B)表示文本值,数字是它们出现在此字典派生自的列表原始列表中的次数。

What I need is a way of printing out the data in the following format. 我需要的是一种以下列格式打印出数据的方法。 For the unique occurrences of the numeric value in the dictionary (ie. in this case the first and third values), print out the associated text value along with its count. 对于字典中数值的唯一出现(即,在本例中为第一个和第三个值),打印出关联的文本值及其计数。 So it would look like 看起来就像

Type: 111 Text Count 键入:111文本计数

       A     4
       B    10

      Total: 14

Type: 112 Text Count 键入:112文本计数

       A      3

     Total:   3

I know I need to use some sort of while loop when combined with If statements. 我知道当与If语句结合使用时,我需要使用某种while循环。 From what I have researched so far (pertinent to what I have been taught so far for Python), I need to write loops with if statements to print only what I want to print. 根据我迄今为止所研究的内容(与我迄今为止为Python所教授的内容相关),我需要使用if语句编写循环以仅打印我想要打印的内容。 So I need to print new Numeric Values the first time they occur, but not the second (or third or fourth, etc) time they occur. 所以我需要在它们第一次出现时打印新的数字值,而不是它们出现的第二个(或第三个或第四个等)时间。 I assume to partially do this I put them in a variable, then compare them to the current value. 我假设部分执行此操作,我将它们放在变量中,然后将它们与当前值进行比较。 If they are the same, I don't print them, but if they are different, I print the "total" of the old numeric values, add it to the overall total, then print the new one. 如果它们是相同的,我不打印它们,但如果它们不同,我打印旧数值的“总数”,将其添加到总数,然后打印新的数值。

Instead of one flat dictionary, I would use a hierarchy of objects, such as dicts inside a dict, tuples inside a dict, etc. 我会使用对象的层次结构,而不是一个平面字典,例如dict中的dicts,dict中的元组等。

Considering an example with dicts inside a dict: 考虑一个dict中的dicts示例:

data = { 
    '111': {
        'A': 4,
        'B': 10,
    },
    '112': {
        'A': 3
    },
}

Now you can more easily access the contents. 现在您可以更轻松地访问内容。 For instance display properties inside '111': 例如'111'中的显示属性:

for key in data['111']:
    print "%s\t%s" % (key, data['111'][key])

The desired output can be created somewhat trivially by combining two for-loops: 通过组合两个for循环,可以在某种程度上轻松创建所需的输出:

for datatype in data:
    print("Type: %s Text Count" % datatype)
    items = data[datatype]
    total = 0
    for key in items:
        print "%s\t%s" % (key, items[key])
        total += items[key]
    print("Total:\t%s\n" % total)

Running the above with the given data would result in the following output: 使用给定数据运行上述操作将导致以下输出:

Type: 111 Text Count
A       4
B       10
Total:  14

Type: 112 Text Count
A       3
Total:  3

It seems to me that a better data structure would be: 在我看来,更好的数据结构将是:

{111:[('A', 4),('B',10)], 112:[('A': 3)]}

Then you can print the dict easily: 然后你可以轻松打印字典:

for k,v in d.items():
   print "Type: {0}\t Text Count".format(k)
   for item in v:
       print "\t\t{0}  {1}".format(*v)

To convert your dict to this form, I'd use a defaultdict : 要将您的dict转换为此表单,我将使用defaultdict

from collections import defaultdict
d = defaultdict(list)
for k,v in yourdict.items():
    new_key,value0 = (x.strip() for x in k.split(','))
    d[int(new_key)].append((value0,v))

Since this is homework, I will give you code that is almost the answer: 既然这是作业,我会给你几乎答案的代码:

myDict = {'111, A': 4, '112, A': 3, '111, B': 10} # input

# keep track of the first half of the composite keys that you've already handled
# This is used to avoid redundant printing
done = set()

for key in myDict:
    # first half of your composite key (eg. '111')
    # I'll be using '111' to explain the rest of the code
    prefix = key.split(',')[0]

    if prefix not in done: # if you haven't already printed out the stuff for '111'
        print prefix # print '111'
        done.add(prefix) # add '111' to done, so that you don't print it out again

        # for all keys in myDict that are of the form "111,X" where X can be anything (e.g. A)
        for k in [k for k in myDict if k.split(',')[0]==prefix]:

            # print a <tab> and the suffix (in our example, "A") and the count value (in myDict, this value is 4)
            print '\t', k.split(',')[1], myDict[k]

Outputs: 输出:

111
     B 10
     A 4
112
     A 3

This requires very small modifications to get you to where you need to be. 这需要非常小的修改,以帮助您到达您需要的位置。

EDIT : "explain how the for k in [k for k in myDict if k.split(',')[0]==prefix]: works" 编辑 :“ for k in [k for k in myDict if k.split(',')[0]==prefix]:解释如何for k in [k for k in myDict if k.split(',')[0]==prefix]:

There are two parts to that statement. 该陈述分为两部分。 The first is a simple for-loop ( for k in … ), which works as usual. 第一个是简单的for循环( for k in … ),它像往常一样工作。 The second is the list comprehension [k for k in myDict if k.split(',')[0]==prefix] . 第二个是列表理解[k for k in myDict if k.split(',')[0]==prefix] This list comprehension can be rewritten as: 此列表理解可以重写为:

myList = []
for k in myDict:
    if k.split(',')[0]==prefix:
        myList.append(k)

and then you would do 然后你会这样做

for k in myList:

There is something to be said about for k in myDict . for k in myDict有一些关于for k in myDict When you iterate over a dict like that, you iterate only over the keys. 当你迭代这样的dict ,你只在键上迭代。 This is the same as saying for k in myDict.keys() . 这与for k in myDict.keys()说法相同。 The difference is that myDict.keys() returns a new list (of the keys in myDict ) which you then iterate over, whereas for k in myDict iterates directly over all the keys in myDict 不同的是, myDict.keys()返回一个新的列表(在按键myDict你然后遍历),而for k in myDict直接通过在所有的按键迭代myDict

You can use tuples as your keys. 您可以使用元组作为键。 Instead of '111, A' try ('111', 'A') 而不是'111, A'尝试('111', 'A')

It allows you to easily loop through the dictionary looking for matches to either the first or second key value. 它允许您轻松遍历字典,查找与第一个或第二个键值匹配的字典。 Just like what you have, except change the key: 就像你拥有的一样,除了更改密钥:

for row in lists: 
    key = (row[0], row[1])
    if key in dictionary: 
        dictionary[key] += 1 
    else: 
        dictionary[key] = 1

#gives
dictionary = {('111', 'A'): 4, ('111', 'B'):10, ('112', 'A'):4}

Now, you're exactly right: you need a variable to store the total, you need to loop through the dictionary, and you need to use conditional statements inside the loop. 现在,你是完全正确的:你需要一个变量来存储总数,你需要循环遍历字典,你需要在循环中使用条件语句。 What exactly are you asking about? 你到底在问什么?

You can loop through the dictionary like this: 您可以像这样遍历字典:

for k in d:
    print k, d[k]

If you keep your string keys, you will need to extract the two values from each key, which you can do with split . 如果保留字符串键,则需要从每个键中提取两个值,这可以通过split (No need to do this step if you use tuples): (如果使用元组,则无需执行此步骤):

#with string keys
key_1, key_2 = k.split(',')

You need to test if the first key value matches the desired number, and then you want to print the letter and the value d[k], and update the total variable: 您需要测试第一个键值是否与所需的数字匹配,然后您要打印字母和值d [k],并更新总变量:

if key_1 == desired:
    print key_2, d[k]
    total += d[k]

So you can put it together, inside a function like this: 所以你可以把它放在一起,在这样的函数中:

def f(d, desired):
    total = 0
    for k in d:
        key_1, key_2 = k.split(',')
        if key_1 == desired:
            print key_2, d[k]
            total += d[k]
    print 'total', total

If you use tuples instead of keys, you can remove the split step, and just use k[0] and k[1] to get the two values: 如果使用元组而不是键,则可以删除拆分步骤,只需使用k [0]和k [1]得到两个值:

def f(d, desired):
    total = 0
    for k in d:
        if k[1] == desired:
            print k[0], d[k]
            total += d[k]

    print 'total', total

I wrote a straightforward function that prints what you want. 我写了一个简单的函数来打印你想要的东西。 It needs the dictionary as the first argument and the type as a int as second (eg fancy_print({'111, A': 4, '112, A': 3,'111, B': 10}, 111) ): 它需要字典作为第一个参数,类型作为第二个int(例如fancy_print({'111, A': 4, '112, A': 3,'111, B': 10}, 111) ):

def fancy_print(d, typ):
    res=[]
    for k in d:
        kp=[q.strip() for q in k.split(',')]
        if int(kp[0])==typ:
            res.append((kp[1],d[k]))
    res.sort()
    print('\tType: %d Text Count' % typ)
    for t,n in res:
        print('\t%s\t%2d' % (t, n))
    print()
    print('\tTotal:\t%2d' % sum([n[1] for n in res]))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM