Python Forum
Сheck if an element from a list is in another list that contains a namedtuple - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Сheck if an element from a list is in another list that contains a namedtuple (/thread-38524.html)



Сheck if an element from a list is in another list that contains a namedtuple - elnk - Oct-25-2022

Hello, i have this code:

def some_generator(some_args):
    Import = namedtuple("Import", ["module", "name", "alias"]) # "module", "name" and "alias" can be listed
...
    for n in node.names:
        yield Import(module, n.name.split('.'), n.asname)
...
files = list()
requirements = list()
...
for member in members:
    files.append(member)
...
for requirement in self.some_generator(some_args):
    requirements.append(requirement)
...
and then i need to check if an element from "files" is in "requirements" (module, name or alias)
how to implement it?


RE: Сheck if an element from a list is in another list that contains a namedtuple - ibreeden - Oct-25-2022

Do you mean this?
for file in files:
    if file in requirements:
        print(f"{file} is in requirements")



RE: Сheck if an element from a list is in another list that contains a namedtuple - elnk - Oct-25-2022

(Oct-25-2022, 05:06 PM)ibreeden Wrote: Do you mean this?
for file in files:
    if file in requirements:
        print(f"{file} is in requirements")

yes, but i have namedtuple (module, name, alias and they can be listed)


RE: Сheck if an element from a list is in another list that contains a namedtuple - deanhystad - Oct-25-2022

This is vague:
yes, but i have namedtuple (module, name, alias and they can be listed)
Do you want to check if file matches any of the fields in the tuple or a particular field?

If there is a match, what do you want to happen?


RE: Сheck if an element from a list is in another list that contains a namedtuple - elnk - Oct-25-2022

(Oct-25-2022, 06:40 PM)deanhystad Wrote: This is vague:
yes, but i have namedtuple (module, name, alias and they can be listed)
Do you want to check if file matches any of the fields in the tuple or a particular field?

If there is a match, what do you want to happen?

"file" is it string, i need to check if an element from "files" (string) is in "requirements" (namedtuple) (module, name or alias)


RE: Сheck if an element from a list is in another list that contains a namedtuple - deanhystad - Oct-25-2022

iberdeen's code does that. Is the problem that it does it for 1 tuple? Here I search multiple tuples (but I have only one file).
from random import randint
from secrets import randbelow

Thing = namedtuple("Thing", ("A", "B", "C"))

things = [Thing(randint(1, 10), randint(1, 10), randint(1, 10)) for _ in range(10)]

for thing in things:
    if 5 in thing:
        print(thing)
Output:
Thing(A=8, B=6, C=5) Thing(A=4, B=5, C=8) Thing(A=5, B=2, C=7)
A namedtuple is still a tuple. The names don't make any difference to "in".

If you have many of these tuples and you want to check many filenames, and you don't really care which tuple is matched (that is a lot of if's), consider making a set that contains all requirements.
from collections import namedtuple
from random import randint
from itertools import chain

Import = namedtuple("Import", ("module", "name", "alias"))
requirements = [Import(randint(1, 1000), randint(1, 1000), randint(1, 1000)) for _ in range(10)]
all_requirements = set(chain(*requirements))  # This will contain every value for module, name and alias that appears in any requirement

files = list(range(100, 200))
for file in files:
    if file in all_requirements:
        print(file)
Output:
126 133



RE: Сheck if an element from a list is in another list that contains a namedtuple - elnk - Oct-26-2022

(Oct-25-2022, 08:15 PM)deanhystad Wrote: iberdeen's code does that. Is the problem that it does it for 1 tuple? Here I search multiple tuples (but I have only one file).
from random import randint
from secrets import randbelow

Thing = namedtuple("Thing", ("A", "B", "C"))

things = [Thing(randint(1, 10), randint(1, 10), randint(1, 10)) for _ in range(10)]

for thing in things:
    if 5 in thing:
        print(thing)
Output:
Thing(A=8, B=6, C=5) Thing(A=4, B=5, C=8) Thing(A=5, B=2, C=7)
A namedtuple is still a tuple. The names don't make any difference to "in".

If you have many of these tuples and you want to check many filenames, and you don't really care which tuple is matched (that is a lot of if's), consider making a set that contains all requirements.
from collections import namedtuple
from random import randint
from itertools import chain

Import = namedtuple("Import", ("module", "name", "alias"))
requirements = [Import(randint(1, 1000), randint(1, 1000), randint(1, 1000)) for _ in range(10)]
all_requirements = set(chain(*requirements))  # This will contain every value for module, name and alias that appears in any requirement

files = list(range(100, 200))
for file in files:
    if file in all_requirements:
        print(file)
Output:
126 133

thank you!
so if i want to delete element from "requirements" wich conrain in "files" is it code right and it work?
        for file in files:
            for requirement in requirements:
                if file in requirement:
                    requirements.remove(requirement)



RE: Сheck if an element from a list is in another list that contains a namedtuple - ibreeden - Oct-26-2022

(Oct-26-2022, 10:32 AM)elnk Wrote: so if i want to delete element from "requirements" wich conrain in "files" is it code right and it work?

for file in files:
    for requirement in requirements:
        if file in requirement:
            requirements.remove(requirement)
No. You must never change a collection while iterating over it. You are iterating over "requirements" and then remove items of it. Instead make a copy of "requirements" and iterate over that copy.


RE: Сheck if an element from a list is in another list that contains a namedtuple - deanhystad - Oct-26-2022

Don't remove, append. I would build a new list that only contains the requirements you want to keep, and I would use set operations to determine which requirements to save
from collections import namedtuple
from random import randint

Import = namedtuple("Import", ("module", "name", "alias"))

files = set(range(100, 200))

# All the requirements
requirements = [Import(randint(1, 1000), randint(1, 1000), randint(1, 1000)) for _ in range(10)]

# Requirements that have no match with any file.
requirements = [req for req in requirements if set(req).isdisjoint(files)]
print(*requirements, sep="\n")