Locate position of an item in a sublist through the main list?

55 Views Asked by At

I have a block of code that look like this:

customer_order1 = []
customer_order2 = []
customer_order3 = []
customer_order4 = []

all_orders = [customer_order1,customer_order2,customer_order3,customer_order4]

All the lists relating to the 'customer_order' only contain 1 item max in each of them. In the list customer_order1 a varible named 'Burger' is located. Ex:

customer_order1 = [Burger]

I'm trying to use the position of 'Burger' to find which list it belongs to in all_orders. Basically, 'Burger' is located in customer_order1, which is position [0] in the all_orders list. After that I can use the location of customer_order1 in all_orders later on in the project. Ex:

if x == all_orders[0]:
    print(" ")
    for y in range (int(number_of_orders1[0])):
      print("", end=" ", flush=True)

To do this I tried using in index function:

x = all_orders.index(Burger)

And I thought that it would find which sublist 'Burger; is stored give me the location of that list inside all_orders. But instead I get:

ValueError: 'Burger(s)' is not in list

I know that 'Burger' (also known as 'Burger(s)') does exist in customer_order1 because previously I ran the command:

if any({Burger}.issubset(sublist) for sublist in all_orders):

This checked if 'Burger' was found in any of the lists inside all_orders.

I've said Burger way too many times. Anyway, could someone provide some help? I tried to provide as much information as possible. I'm new to Python and new to programming in general.

2

There are 2 best solutions below

0
Antoine On BEST ANSWER

It's because you have a burger in a list, so you need to find "buger in a list" inside your all_orders Basicaly doing : x = all_orders.index([burger])

Demo

Here a verbose exemple

>>> class Burger:
...     pass
...
>>> burger = Burger()
>>> burger
<__main__.Burger object at 0x7fc6137830d0>
>>> customer_order1=[burger,]
>>> customer_order1
[<__main__.Burger object at 0x7fc6137830d0>]
>>> customer_order2 = []
>>> customer_order3 = []
>>> customer_order4 = []
>>> all_orders = [customer_order1,customer_order2,customer_order3,customer_order4]
>>> all_orders
[[<__main__.Burger object at 0x7fc6137830d0>], [], [], []]
>>> x = all_orders.index(burger)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: <__main__.Burger object at 0x7fc6137830d0> is not in list
>>> x = all_orders.index([burger])
>>> x
0 # HERE you have your index 
0
Táwros On

You cannot search for elements in the nested lists by only referencing the main list. You must define a custom indexing function to search those nested lists. Here is a recursive one that you can use.

import operator as __operator
from typing import Any, Callable


def extended_index(arr: list, target, *, operator: Callable[[Any, Any], bool] | None = None) -> int | tuple[int] | None:
    """Returns the index of the target value in the array. If the target value is not found, returns None.

    Performs a depth-first search of the array and any nested lists. If the target value
    is found in a nested list, returns a tuple of the indices of the target value.

    Args:
        arr (list): The array to search.
        target (int): The target value to search for.
        operator (Callable[[Value: Any, Target: Any], bool], optional): The operator to compare the element and target. Defaults to `__eq__`.

    Returns:
        int | tuple[int] | None: The index of the target value in the array, or None if the target value is not found.

    Examples:
        >>> extended_index([1, 2, 3], 2)
        1
        >>> extended_index([1, 2, 3], 4)
        None
        >>> extended_index([[1, 2, 3], [4, 5, 6]], 6)
        (1, 2)
        >>> extended_index([[1, 2, 3], [4, 5, 6]], [4, 5, 6])
        1
        >>> class Foo:
        ...     bar = 1
        ...
        >>> extended_index([[1, Foo()], [2, 3]], Foo, operator=lambda element, target : isinstance(element, target))
        (0, 1)
    """
    if operator is None:
        operator = __operator.__eq__

    for i, v in enumerate(arr):
        if isinstance(v, list):
            # Check sub-lists
            j = extended_index(v, target, operator=operator)
            if j is not None:
                if isinstance(j, tuple):
                    return (i, *j)
                else:
                    return (i, j)
            elif operator(v, target):
                # Check list itself
                return i
        elif operator(v, target):
            return i

I added a checking argument to the function in case you need some custom logic to check and see if the value is the one you're looking for.

burger = ...
all_orders = [
    [0, burger,],
    ["stuff", None],
]
x = extended_index(all_orders, burger)
print(x)

Should print

(0, 1)