2

I'm a beginner using Python and I'm stuck.

I've imported some data from two separate CSV files and added them to relevant variables:

List_1 = [['01', 'Banana', '2', '10'],['02', 'Apple', '1', '10'],
          ['03', 'Orange', '3', '10']]

Explanation of values: [Item number, Item, Item cost, Item Stock]

List_2 = [['02','3'],['01','1'],['03','5']]

Explanation of values: [Item number, Amount paid]

I need to match the 1st value in List_2 i.e 02 with the item number in List_1 i.e the 1st item. Then retrieve he attributed cost, in this example 2.

I hope this makes sense. I've tried a few times with different syntax etc and failed miserably.

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
JAM
  • 125
  • 1
  • 2
  • 12
  • Have you tried using `dict` instead of `list`? The `key` would be your *Item number*, and the `value`, the rest of items in your current lists. Matching them by key would be a breeze. – chapelo Dec 20 '16 at 12:56
  • I will give it a try, thank you. – JAM Dec 20 '16 at 12:57
  • Can I create a dictionary from the lists I already have? – JAM Dec 20 '16 at 12:57
  • @JAM, yes you can. You might want to check dict comprehension, see this [answer](http://stackoverflow.com/a/1747827/4788274)... – José Sánchez Dec 20 '16 at 12:59

3 Answers3

1

You can build two dictionaries:

items = {entry[0]: {'item': entry[1], 'cost': float(entry[2]), 'stock': int(entry[3])} 
         for entry in List_1}
paid = {id_: int(count) for id_, count in List_2}

and can now match both datasets:

for id_, count in paid.items():
    item = items[id_]
    print(item['item'], item['cost'] * count)

Output:

Banana 2.0
Apple 3.0
Orange 15.0
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
0

Not a very pythonic solution, but I think this should make the logic clear:

for l2 in List_2:
    for l1 in List_1:
        if l2[0] == l1[0]:
            print("cost for {} is: {}".format(l1[1], l1[2]))
José Sánchez
  • 1,126
  • 2
  • 11
  • 20
  • 1
    You need a `break` after your `print`, so that once you find the match you won't keep looking until both lists are exhausted. I think that your solution is "pythonic" in the sense that you are expressing good python code. However, it is inefficient because you need to traverse both lists to find a match. In the worst case, the match would be the last element. This algorithm would be slow with long lists. – chapelo Dec 20 '16 at 21:36
0

The best solution would be to produce the dictionaries at the time of reading the CSV file, and at the same time change each data from a string to the appropriate type (float or int).

If you want to transform the current lists to dicts, and you are using Python 3, you can do it this way:

D = lambda L: {k: tuple(v) for k, *v in L}

D1 = D(List_1)
D2 = D(List_2)

print(D1)
# {'02': ('Apple', '1', '10'), '01': ('Banana', '2', '10'), '03': ('Orange', '3', '10')}

print(D2)
# {'01': ('1',), '02': ('3',), '03': ('5',)}

Note that using tuples is preferred to using lists in cases such as this one where the data won't change. However, if you need to change the values by appending, inserting or deleting other data, you will need to use lists.

if you want to follow Mike's idea of using dicts also for the values, you need to provide another argument with the fields:

D = lambda L, fields: {k: dict(zip(fields, v)) for k, *v in L}

D1 = D(List_1, ('item', 'cost', 'stock'))
D2 = D(List_2, ('paid',))

print(D1)
# {'02': {'cost': '1', 'stock': '10', 'item': 'Apple'}, '01': {'cost': '2', 'stock': '10', 'item': 'Banana'}, '03': {'cost': '3', 'stock': '10', 'item': 'Orange'}}

print(D2)
# {'01': {'paid': '1'}, '02': {'paid': '3'}, '03': {'paid': '5'}}
chapelo
  • 2,519
  • 13
  • 19