简体   繁体   English

使用 *args 和 **kwargs 的字典理解

[英]Dictionary comprehension using *args and **kwargs

I'm new to Python. I have to do a little exercise.我是 Python 的新手。我必须做一些练习。 I have two classes RealNumber and ComplexNumber and I need to create a new class, with, as an attribute, a dictionary (dict_number) that contains an integer as a key and a RealNumber or ComplexNumber object as value.我有两个类 RealNumber 和 ComplexNumber,我需要创建一个新的 class,作为一个属性,一个包含 integer 作为键和 RealNumber 或 ComplexNumber object 作为值的字典 (dict_number)。 In the init method, with parameters *args and **kwargs, each arg in *args must be entered with an increasing integer key (using the dict comprehension) (eg {0: RealNumber0, 1: RealNumber1, 2: ComplexNumber0}) while for each arg in kwargs it will be necessary to insert the parameter name: value.init方法中,参数 *args 和 **kwargs,*args 中的每个 arg 必须使用递增的 integer 键输入(使用字典理解)(例如 {0: RealNumber0, 1: RealNumber1, 2: ComplexNumber0})而对于 kwargs 中的每个参数,都需要插入参数名称:值。 Now, I have already created the classes RealNumber and ComplexNumber, but I'm having issues doing the third class. How can I create a dict that have an incremental value as key and a tuple (object name, object value) as value?现在,我已经创建了 RealNumber 和 ComplexNumber 类,但是我在执行第三个 class 时遇到了问题。如何创建一个以增量值作为键和一个元组(对象名称,object 值)作为值的字典? The dictionary must have this form: {incremental key: (name_object, object value)} , for example: {0: Realnumber 5, 1: ComplexNumber 1+3i...} Where 0: is the incremental key;字典必须有这样的形式: {incremental key: (name_object, object value)} ,例如: {0: Realnumber 5, 1: ComplexNumber 1+3i...}其中0:是增量键; Realnumber is the name of the object class; Realnumber是object class的名字; 5 is the value contained by the Realnumber class object. 5Realnumber class object 包含的值。

...

class NumbersCollection:  # I've issues here
     def __init__(self, *args, **kwargs):
         self.dict_numbers = {key: arg for key, arg in kwargs.items()} 

if __name__ == '__main__':
    x = RealNumber(5)
    y = ComplexNumber(1, 3) #first parameter is the real part, the 2nd is the imaginary part

    print(f"Number: {x.number}")
    print(f"RealPart: {y.numPart}, ImPart: {y.imPart}")

    d = NumbersCollection(a=x, b=y) # I've issues here

...

How about this?这个怎么样?

class NumbersCollection:
    def __init__(self, **kwargs):
        self.dict_numbers = {
            i: (key, value) for i, (key, value) in enumerate(kwargs.items())
        }
>>> nums = NumbersCollection(a=1, b=2)
>>> nums.dict_numbers
{0: ('a', 1), 1: ('b', 2)}

To be honest, you are asking too many questions in a single question.老实说,你在一个问题中问了太多问题。 So there is another answer.所以还有另一个答案。

__repr__

You can modify representation of an object of a class defining __repr__ method on a class:您可以修改 class 的 object 的representation ,在 class 上定义__repr__方法:

class SomeClass:
    def __init__(self, value: int) -> None:
        self.value = value

    def __repr__(self):
        return f"SomeClass {self.value}"
>>> SomeClass(1)
SomeClass 1

enumerate

You can use enumerate function on an iterable to iterate objects in a sequence, returning index as first value and value of an object as second value您可以在可迭代对象上使用enumerate function 来迭代序列中的对象,返回index作为第一个值,返回 object 的value作为第二个值

data = {
    "a": 1,
    "b": 2,
    "c": 3,
}
>>> for i, (key, value) in enumerate(data.items()):
...     print(i, key, value)
...
0 a 1
1 b 2
2 c 3

Answering your question,回答你的问题,

combine this techniques to get the desired answer.结合这些技术以获得所需的答案。

Using __repr__ :使用__repr__

class RealNumber:
    def __init__(self, value: int) -> None:
        self.value = value

    def __repr__(self):
        return f"RealNumber {self.value}"


class ComplexNumber:
    def __init__(self, value: int, imaginary_part: int) -> None:
        self.real_part = value
        self.imaginary_part = imaginary_part

    def __repr__(self):
        return f"ComplexNumber {self.real_part}+{self.imaginary_part}i"

Using enumerate :使用enumerate

class NumbersCollection:
    def __init__(self, *args: Union[RealNumber, ComplexNumber]):
        self.dict_numbers = dict(enumerate(args))

The use of dictionary comprehension there is not required as dict(enumerate(args)) does the same, but better and cleaner.不需要使用字典理解,因为dict(enumerate(args))做同样的事情,但更好更清洁。 You can, of course, use them if it is a requirement of your assignment.当然,如果这是您作业的要求,您可以使用它们。

class NumbersCollection:
    def __init__(self, *args: Union[RealNumber, ComplexNumber]):
        self.dict_numbers = {i: value for i, value in enumerate(args)}

Both should produce the same answer.两者都应该产生相同的答案。

>>> nums = NumbersCollection(RealNumber(1), ComplexNumber(1, 2))
>>> nums.dict_numbers
{0: RealNumber 1, 1: ComplexNumber 1+2i}

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

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