electricmanh
electricmanh

Reputation: 11

Replacing elements of a list in python

I have the original list with dictionaries inside it for 3 drinks and their corresponding prices and stock levels.

products = [
    {
        "name": "coke",
        "price": 3,
        "stock": 10
    },
    {
        "name": "bepis",
        "price": 2,
        "stock": 232
    },
    {
        "name": "fanta",
        "price": 2,
        "stock": 144
    }
[

If I had 3 lists such as these:

["mdew", "water", "tea", "tapwater"] # names
["3", "10", "3", "40"] # prices
["10", "10", "10"] # stock levels, tap water is out of stock so there are only 3 values here

As seen above there are 3 new lists but now there are 4 total drinks. The lists correspond to each other e.g mdew - 3 - 10, water 10 - 10, tea - 3 - 10, tapwater - 40 - EMPTY.

How could I go about recreating the first list, replacing the values with the 3 lists? Sorry if this was poorly worded.

Thank you!

Upvotes: 0

Views: 39

Answers (1)

AKX
AKX

Reputation: 168863

You'd ordinarily use zip() to "zip up" multiple iterables to iterate over simultaneously:

for (name, price, stock) in zip(names, prices, stocks):
    print(f"{name=}, {price=}, {stock=}")

The output would be

name='mdew', price='3', stock='10'
name='water', price='10', stock='10'
name='tea', price='3', stock='10'

– notice the conspicuous lack of tap water.

Since one iterable is shorter than the others, you'll need itertools.zip_longest.

After that, generating a list of dicts is just a list comprehension away.

import itertools

names = ["mdew", "water", "tea", "tapwater"]
prices = ["3", "10", "3", "40"]
stocks = ["10", "10", "10"]

products = [
    {"name": name, "price": price, "stock": stock or 0}
    for (name, price, stock) in itertools.zip_longest(names, prices, stocks)
]

print(products)

The output is

[
  {'name': 'mdew', 'price': '3', 'stock': '10'},
  {'name': 'water', 'price': '10', 'stock': '10'},
  {'name': 'tea', 'price': '3', 'stock': '10'},
  {'name': 'tapwater', 'price': '40', 'stock': 0},
]

EDIT:

If you don't want to use itertools (for whichever reason), you can write something like zip_longest yourself (this is intentionally simplified to require len()able iterables):

def zip_longest_lists(*lists):
    max_len = max(len(l) for l in lists)
    for i in range(max_len):
        yield tuple((l[i] if i < len(l) else None) for l in lists)

Upvotes: 1

Related Questions