私信  •  关注

Pranav Hosangadi

Pranav Hosangadi 最近创建的主题
Pranav Hosangadi 最近回复了
2 年前
回复了 Pranav Hosangadi 创建的主题 » 在Python中,可以将列表中的元素添加到字典的值中吗?

是的 x = 1 ,然后你马上 for x in d2.values() .这会覆盖 x 每一个元素 d2.values() .如果你想从第二项开始 d2。价值观() ,需要创建迭代器并跳过第一个值:

d2_iter = iter(d2.values())
next(d2_iter) # Consume one element
for item in d2_iter: # Iterate over the remaining iterator
    # Do what you want here.

另一个问题是附加 整个列表 每一个价值 在里面 d2 .不要那样做。改用 zip() 遍历列表列表和中的值 d2 同时

d2_iter = iter(d2.values())
next(d2_iter) # Consume one element
for item_from_dict, item_to_append in zip(d2_iter, list_of_lists): 
    item_from_dict.append(item_to_append)

这就给你留下了:

{'Youngstown': ['OH', 4110, 8065, 115436],
 'Yankton': ['SD', 4288, 9739, 12011, [966]],
 'Yakima': ['WA', 4660, 12051, 49826, [1513, 2410]]}

请注意,像这样的附加只起作用,因为列表是可变的。如果有一个不可变的类型,比如元组,作为 d2 ,则必须创建一个新元组并将其分配给键:

d3 = {'Youngstown': ('OH', 4110, 8065, 115436), 'Yankton': ('SD', 4288, 9739, 12011), 'Yakima': ('WA', 4660, 12051, 49826)}

d3_iter = iter(d2.keys())
next(d3_iter) # Consume one element

for key_from_dict, item_to_append in zip(d3_iter, list_of_lists): 
    new_item = d3[key_from_dict] + (item_to_append,) # Create a new item
    d3[key_from_dict] = new_item

你会得到

{'Youngstown': ('OH', 4110, 8065, 115436),
 'Yankton': ('SD', 4288, 9739, 12011, [966]),
 'Yakima': ('WA', 4660, 12051, 49826, [1513, 2410])}
3 年前
回复了 Pranav Hosangadi 创建的主题 » 在Python中,如何使用方法参数作为新对象的名称?

你不愿意吗 AMZN 加入 Portfolio 你创建的对象?考虑一下你拥有多个投资组合的场景,所有的投资组合都拥有AMZN股票。AMZN控股公司应该是谁 AMZN.amount 提到

此外,假设我以3000英镑的价格购买20股AMZN股票,以1500英镑的价格再购买20股AMZN股票,它应该指的是这些购买中的哪一种?它应该给你一个 列表 属于 Stock 那个股票行情器的对象?

我建议你定义 Portfolio.stockPortfolio 作为一个 collections.defaultdict 对象然后,你可以定义一个 __getitem__() 方法 文件夹 以股票代码为例 p["AMZN"] 并从中返回正确的列表 stockPortfolio .如果你真的想使用以下属性访问投资组合的资产 p.AMZN ,你可以定义 __getattr__() 方法然而,我强烈推荐你 不要 这样做是因为@martineau在他们的 comment 上图: Why you don't want to dynamically create variables Keep data out of your variable names.

import collections

class Stock:
    def __init__(self, ticker, price, amount):
        self.ticker = ticker
        self.price = price
        self.amount = amount
        
    def __repr__(self):
        return f"Stock('{self.ticker}', {self.price}, {self.amount})"

# Create portfolio to hold stocks and available funds
class Portfolio:
    def __init__(self, funds):
        self.funds = funds
        self.stockPortfolio = collections.defaultdict(list)
        
# Buying a stock and adding it to the portfolio               
    def buyStock(self, ticker, price, amount):
        #Add stock to portfolio
        stk = Stock(ticker, price, amount)
        self.stockPortfolio[ticker].append(stk)    

    def __getitem__(self, ticker):
        return self.stockPortfolio[ticker]

    def __getattr__(self, ticker):
        return self.stockPortfolio[ticker]

我加了一个 __repr__ 股票 这样我们就可以看到列表中的库存对象包含了什么。

p = Portfolio(100000)

p.buyStock("AMZN", 3000, 20)
print(p["AMZN"])
# Output: [Stock('AMZN', 3000, 20)]

p.buyStock("AMZN", 3500, 10)
print(p.AMZN)
# Output: [Stock('AMZN', 3000, 20), Stock('AMZN', 3500, 10)]

延长 @chepner's excellent answer ,您可以定义自己的类并使用其 __getattr__ 函数创建一个函数,用预处理和后处理函数包装实际模块的函数:

import typing
import xyz

def XYZWrapper():
    def __init__(self, pre, post):
        self.pre = pre
        self.post = post

    def __getattr__(self, a):
        func = getattr(xyz, a)
        if isinstance(func, typing.Callable):
            def wrapper(*args, **kwargs):
                self.pre()
                func(*args, **kwargs)
                self.post()
            return wrapper
        raise TypeError(f"'{type(func)}' object is not callable")

要使用它,就去做

xyz = XYZWrapper(prepare, done)
xyz.foo(<args>)
...

请注意,如果要覆盖 xyz 变量,则需要将包装器类放在单独的文件中。