Python equivalent for C#'s generic List<T>
Asked Answered
G

2

5

I am creating a simple GUI program to manage priorities.

Priorities

I have successfully managed to add functionality to add an item to the listbox. Now I want to add the item to the something what is known as List<> in C#. Does such a thing exist in Python?

For instance, in C#, to add an item to the listview I would first create:

List<Priority> priorities = new List<Priority>();

...and then create the following method:

void Add()
{
    if (listView1.SelectedItems.Count > 0)
    {
        MessageBox.Show("Please make sure you have no priorities selected!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else if (txt_Priority.ReadOnly == true) { MessageBox.Show("Please make sure you refresh fields first!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information); }
    else
    {
        if ((txt_Priority.Text.Trim().Length == 0)) { MessageBox.Show("Please enter the word!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information); }
        else
        {
            Priority p = new Priority();
            p.Subject = txt_Priority.Text;

            if (priorities.Find(x => x.Subject == p.Subject) == null)
            {
                priorities.Add(p);
                listView1.Items.Add(p.Subject);
            }
            else
            {
                MessageBox.Show("That priority already exists in your program!");
            }
            ClearAll();
            Sync();
            Count();
        }
    }
    SaveAll();

}
Golter answered 2/4, 2017 at 12:32 Comment(1)
And you couldn't find any information searching for "Python list"?!Nymph
H
4

Type hints

Since Python 3.5, it's possible to add type hints. Coupled with dataclasses (Python 3.7+), and generic collections (Python 3.9+), you can write:

from dataclasses import dataclass


@dataclass
class Priority:
    """Basic example class"""
    name: str
    level: int = 1


foo = Priority("foo")
bar = Priority("bar", 2)

priorities: list[Priority] = [foo, bar]

print(priorities)
# [Priority(name='foo', level=1), Priority(name='bar', level=2)]
print(sorted(priorities, key= lambda p: p.name))
# [Priority(name='bar', level=2), Priority(name='foo', level=1)]

baz = "Not a priority"
priorities.append(baz) # <- Your IDE will probably complain

print(priorities)
# [Priority(name='foo', level=1), Priority(name='bar', level=2), 'Not a priority']

In Python 3.5, the code would look like:

from typing import List


class Priority:
    """Basic example class"""
    def __init__(self, name: str, level: int = 1):
        self.name = name
        self.level = level

    def __str__(self):
        return '%s (%d)' % (self.name, self.level)

    def __repr__(self):
        return str(self)


foo = Priority("foo")
bar = Priority("bar", 2)

priorities: List[Priority] = [foo, bar]

print(priorities)
# [foo (1), bar (2)]
print(sorted(priorities, key=lambda p: p.name))
# [bar (2), foo (1)]

baz = "Not a priority"
priorities.append(baz) # <- Your IDE will probably complain

print(priorities)
# [foo (1), bar (2), 'Not a priority']

Note that type hints are optional, and the above code will run fine, even if there's a type mismatch when appending baz.

You can explicitly check for errors with mypy:

❯ mypy priorities.py
priorities.py:22: error: Argument 1 to "append" of "list" has incompatible type "str"; expected "Priority"
Found 1 error in 1 file (checked 1 source file)

Dynamic language

Even if it now has type hints, Python stays dynamic, and type hints are completely optional:

>>> my_generic_list = []
>>> my_generic_list.append(3)
>>> my_generic_list.append("string")
>>> my_generic_list.append(['another list'])
>>> my_generic_list
[3, 'string', ['another list']]

You don't have to define anything before appending any object to an existing list.

Python uses duck-typing. If you iterate on a list and call a method on each one of the elements, you need to make sure that the elements understand the method.

So if you want the equivalent of :

List<Priority> priorities

you just need to initialize a list and make sure you only add Priority instances to it. That's it!

Histochemistry answered 2/4, 2017 at 12:47 Comment(3)
what about forcing the list to be of a type? would I need to create a class with an append method that would throw an exception when the type is not what should be?Dharna
@gabrielgarcia: If you want to check explicitely, you could use Python type hints. For example : from typing import List; Vector = List[float];def scale(scalar: float, vector: Vector) -> Vector:...Histochemistry
I updated the answer, in order to include newer python features.Histochemistry
W
4

Fortunately generic collections are supported since Python 3.9 (3.8): https://docs.python.org/3/library/typing.html#generic-concrete-collections
Here is an example:

listOfInts: list[int] = []

# dictionary with string keys and int values:
typedDict: dict[str, int] = []
Washcloth answered 1/6, 2021 at 11:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.