简体   繁体   English

如何有效地遍历字典?

[英]How to efficiently iterate through a dictionary?

I'm new to Python and programming. 我是Python和编程的新手。

My textbook says I have to do the following problem set: 我的教科书上说我必须做以下问题:

Create a second purchase summary that which accumulates total investment by ticker symbol. 创建第二个采购摘要,该摘要会用股票代号来累计总投资。 In the above sample data, there are two blocks of CAT. 在上面的示例数据中,有两个CAT块。

These can easily be combined by creating a dict where the key is the ticker and the value is the list of blocks purchased. 通过创建一个dict可以轻松地将它们组合起来,其中的关键是股票行情指示器,值是购买的区块列表。 The program makes one pass through the data to create the dict. 该程序对数据进行一次遍历以创建字典。 A pass through the dict can then create a report showing each ticker symbol and all blocks of stock. 然后,通过dict可以创建一个报告,其中显示每个股票代码和所有股票区块。

I cannot think of a way, apart from hard-coding, to add the two entries of the 'CAT' stock. 除了硬编码,我想不出一种方法来添加“ CAT”股票的两个条目。

## Stock Reports

stockDict = {"GM":"General Motors", "CAT":"Caterpillar", "EK":"Eastman Kodak",
             "FB":"Facebook"}
# symbol,prices,dates,shares
purchases = [("GM",100,"10-sep-2001",48), ("CAT",100,"01-apr-1999",24),
             ("FB",200,"01-jul-2013",56), ("CAT", 200,"02-may-1999",53)]

# purchase history:
print "Company", "\t\tPrice", "\tDate\n"
for stock in purchases:
    price = stock[1] * stock[3]
    name = stockDict[stock[0]]
    print name, "\t\t", price, "\t", stock[2]
print "\n"

# THIS IS THE PROBLEM SET I NEED HELP WITH:
# accumulate total investment by ticker symbol
byTicker = {}
# create dict
for stock in purchases:
    ticker = stock[0]
    block = [stock]
    if ticker in byTicker:
        byTicker[ticker] += block
    else:
        byTicker[ticker] = block

for i in byTicker.values():
    shares = i[0][3]
    price = i[0][1]
    investment = shares * price
    print investment

Right now, the output is: 现在,输出为:

4800
11200
2400

It's not good because it does not calculate the two CAT stocks. 不好,因为它不计算两个CAT库存。 Right now it only calculates one. 现在,它只计算一个。 The code should be flexible enough that I could add more CAT stocks. 该代码应该足够灵活,可以添加更多的CAT库存。

Maybe something like this: 也许是这样的:

## Stock Reports

stockDict = {"GM":"General Motors", "CAT":"Caterpillar", "EK":"Eastman Kodak",
             "FB":"Facebook"}
# symbol,prices,dates,shares
purchases = [("GM",100,"10-sep-2001",48), ("CAT",100,"01-apr-1999",24),
             ("FB",200,"01-jul-2013",56), ("CAT", 200,"02-may-1999",53)]

# purchase history:
print "Company", "\t\tPrice", "\tDate\n"
for stock in purchases:
    price = stock[1] * stock[3]
    name = stockDict[stock[0]]
    print name, "\t\t", price, "\t", stock[2]
print "\n"

# THIS IS THE PROBLEM SET I NEED HELP WITH:
# accumulate total investment by ticker symbol
byTicker = {}
# create dict
for stock in purchases:
    ticker = stock[0]
    price = stock[1] * stock[3]
    if ticker in byTicker:
        byTicker[ticker] += price
    else:
        byTicker[ticker] = price

for ticker, price in byTicker.iteritems():
    print ticker, price

The output I get is: 我得到的输出是:

Company                 Price   Date

General Motors          4800    10-sep-2001
Caterpillar             2400    01-apr-1999
Facebook                11200   01-jul-2013
Caterpillar             10600   02-may-1999


GM 4800
FB 11200
CAT 13000

which appears to be correct. 这似乎是正确的。

Testing whether or not a ticker is in the byTicker dict tells you whether or not there's already been a purchase recorded for that stock. 测试byTicker字典中的byTicker是否告诉您是否已经记录了该股票的购买。 If there is, you just add to it, if not, you start fresh. 如果有,则只需添加即可;如果没有,则可以重新开始。 This is basically what you were doing, except for some reason you were collecting all of the purchase records for a given stock in that dict, when all you really cared about was the price of the purchase. 这基本上就是您正在做的事情,除了出于某种原因,您要收集的所有购买记录都取决于该价格,而这只取决于您购买价格。

You could build the dict the same way you were originally, and then iterate over the items stored under each key, and add them up. 您可以使用最初的方式来构建dict,然后遍历每个键下存储的项目,并将其加起来。 Something like this: 像这样:

totals = []
for ticker in byTicker:
    total = 0
    for purchase in byTicker[ticker]:
        total += purchase[1] * purchase[3]
    totals.append((ticker, total))

for ticker, total in totals:
    print ticker, total

And just for kicks, you could compress it all into one line with generator statements: 只是为了踢球,您可以使用生成器语句将其全部压缩为一行:

 print "\n".join("%s: %d" % (ticker, sum(purchase[1]*purchase[3] for purchase in byTicker[ticker])) for ticker in byTicker)

Either of these last two are completely unnecessary to do though, since you're already iterating through every purchase, you may as well just accumulate the total price for each stock as you go, as I showed in the first example. 最后两个中的任何一个都不是完全必要的,因为您已经在每次购买中进行了迭代,所以您最好随便累积每只股票的总价,如我在第一个示例中所示。

Your problem is in the last part of your code, the penultimate bit creates a list of all stocks against each ticker, which is fine: 您的问题出在代码的最后部分,倒数第二个位针对每个股票创建了所有股票的列表,这很好:

for i in byTicker.values():
    shares = i[0][3]
    price = i[0][1]
    investment = shares * price
    print investment

Here you only use the zeroth stock for each ticker. 在这里,您对每个股票使用零号股票。 Instead, try: 相反,请尝试:

for name, purchases in byTicker.items():
    investment = sum(shares * price for _, shares, _, price in purchases)
    print name, investment

This will add up all of the stocks for each ticker, and for your example gives me: 这将合计每个股票的所有股票,而您的示例为我提供了:

CAT 13000
FB 11200
GM 4800

The problem with your code is that you are not iterating over the purchaes, but just getting the first element from each ticker value. 您的代码的问题在于您不是在遍历购买,而是从每个报价器值中获取第一个元素。 That is, byTicker looks something like: 也就是说,byTicker看起来像:

byTicker: {
  "GM": [("GM",100,"10-sep-2001",48)],
  "CAT": [("CAT",100,"01-apr-1999",24), ("CAT", 200,"02-may-1999",53)],
  "FB": [("FB",200,"01-jul-2013",56)]
}

so when you iterate over the values, you actually get three lists. 因此,当您遍历值时,实际上会得到三个列表。 But when you process these lists, you are actually accessing only the first of them: 但是,当您处理这些列表时,实际上您仅访问其中的第一个:

price = i[0][1]

for the value corresponding to "CAT", i[0] is ("CAT",100,"01-apr-1999",24). 对于对应于“ CAT”的值,i [0]为(“ CAT”,100,“ 01-apr-1999”,24)。 You should look into i[1] as well! 您也应该研究i [1]! Consider iterating over the different purchases: 考虑迭代不同的购买:

for company, purchases in byTicker.items():
  investment = 0
  for purchase in purchases:
      investment += purchase[1] * purchase[3]
  print(company, investment)

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

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