-1

I'm trying to compare 2 string lists in python, suppose I have this 2 lists:

list_one = ['con good', 'con good', 'tech', 'retail', 'con good',
           'con good', 'retail', 'finance', 'finance', 'retail',
           'retail', 'finance', 'tech', 'retail', 'tech',
           'finance', 'con good', 'tech', 'con good', 'tech']

and

list_two =      ['yes', 'yes', 'yes', 'no', 'no',
                 'no', 'no', 'yes', 'yes', 'yes',
                 'yes', 'yes', 'yes', 'no', 'no',
                 'no', 'no', 'yes', 'yes', 'no']

how to iterate a variable correctly if there is item x in index y list_one and item a index y in list_two

for example, how do I check if 'con good' in list_one is in the same position with 'yes' in list_two (both in index 0)

I tried using for loop like this

tech = 0

for i in list_one:
    for j in list_two:
        if i == 'tech' and j == 'yes':
            tech = tech+1

print tech

but it returned 55 when it should've returned 3. Please help me

Iqbal Pratama
  • 139
  • 1
  • 5
  • 14
  • 1
    Use the zip builtin, will take two iterables and provide tuples of both items. – Tim Jul 25 '17 at 04:38
  • The problem with your loops is that you count all yesses in the second list (11 of them) every time you encounter a tech in the first list (5 times). 5x11 = 55, as expected. – Mad Physicist Jul 25 '17 at 04:46

7 Answers7

3

This can be reduced to a single line if you take advantage of the tools provided by python eg:

>>> from collections import Counter
>>> counts = Counter(one for one, two in zip(list_one, list_two) if two == 'yes')

>>> print(counts)
Counter({'con good': 3, 'tech': 3, 'finance': 3, 'retail': 2})

>>> print(counts['tech'])
3

Zip will combine the two lists, Counter will count up items in an iterable.

Tim
  • 2,510
  • 1
  • 22
  • 26
  • This would be my preferred way if I needed more than one count - `O(n)` to construct and then `O(1)` for each lookup. – AChampion Jul 25 '17 at 04:59
2
tech = 0

for i in range(len(list_one)):
    if list_one[i] == 'tech' and list_two[i] == 'yes':
        tech = tech+1

print tech

Test to run your code manually on a paper. Each time you hit tech in list_one, what you're code is doing is basically to count the number of yes in the whole list_two.

A more Pythonic way to do it is:

tech = 0
for i in zip(list_one, list_two):
    if i == ('tech', 'yes'):
        tech = tech + 1

Using list comprehension:

len([a for a in zip(list_one, list_two) if a == ('tech', 'yes')])
klutt
  • 30,332
  • 17
  • 55
  • 95
  • Not very Pythonic, but technically correct except that you probably meant `range(len(list_one))`. – Mad Physicist Jul 25 '17 at 04:42
  • @MadPhysicist True, but in this case I thought it was the best way to make OP understand *why* it was wrong, and not just get a quick fix. – klutt Jul 25 '17 at 04:43
  • Thanks, it worked! I see it now, I used nested loop before, no wonder it iterate the whole second list – Iqbal Pratama Jul 25 '17 at 04:47
  • I don't disagree with your method. The downvote was not for being unpythonic or anything like that. It's for posting broken code, which you still haven't fixed. – Mad Physicist Jul 25 '17 at 04:48
  • Yes it is fixed now. – klutt Jul 25 '17 at 04:49
  • A slightly similar list comprehension I wrote: `sum([1 for i in range(len(list_two)) if (list_one[i] == 'tech' and list_two[i] == 'yes')])` It's pretty ugly, though... :( – Cory Madden Jul 25 '17 at 04:52
  • I fixed my vote and made an edit I hope you won't mind. – Mad Physicist Jul 25 '17 at 04:52
  • @MadPhysicist I don't mind at all. Thank you. – klutt Jul 25 '17 at 04:54
  • @Cory. You can truncate that to `sum((list_one[i] == 'tech' and list_two[i] == 'yes') for i in range(len(list_one)))`. This works because bools are actually a subclass of int, where True is always exactly one and False is always zero. – Mad Physicist Jul 25 '17 at 04:56
  • 1
    Oh, of course. I just explained that to one of my coworkers the other day who had written something slightly worse than `bool(int(some_value))` – Cory Madden Jul 25 '17 at 04:58
  • @AChampion. Caught in time for me to fix it. Thx. – Mad Physicist Jul 25 '17 at 05:00
2

As pointed out zip is the way to go, e.g.:

>>> tech = sum(e == ('con good', 'yes') for e in zip(list_one, list_two))
>>> tech
3

Note: you ask for 'con good' but your code is checking for 'tech' both of which return 3

AChampion
  • 29,683
  • 4
  • 59
  • 75
0

my interpretation

match = sum([1 for k,v in zip(list_one, list_two) if k == 'con good' and v == 'yes'])
José Garcia
  • 136
  • 9
0

Assuming you would like to count all occurrences of items in a list

You can use enumerate here as well

# Initialize counts dict, Or you can use Counter here as well.
counts = {}
for i,item in enumerate(list_one):
    counts[item] = 0

# counts => {'con good': 0, 'tech': 0, 'finance': 0, 'retail': 0}

# Count actual occurrences
for i, item in enumerate(list_one):
    if(list_two[i] == 'yes'):
        counts[item] += 1

# counts => {'con good': 3, 'tech': 3, 'finance': 3, 'retail': 2}
Kashif Siddiqui
  • 1,476
  • 14
  • 26
0
for i,j in enumerate(list_one):
    for k,l in enumerate(list_two):
        if i==k:
            if j=='con good' and l=='yes':
                print(i)

you can also use list comprehension and using enumerate() iterate over index and value of list:

result = [i for i,j in enumerate(list_one) for k,l in enumerate(list_two) if i==k if j=='con good' and l=='yes']
ammy
  • 618
  • 1
  • 5
  • 13
0
# get unique values from the list by converting it to set, then to list again
# this will output ['con good', 'tech', 'finance', 'retail']
list_three = list(set(list_one))

# for every word in list_three, find it in list_one
# check if it's a yes in list_two 
for i in list_three:
  tech = 0
  for j in range(len(list_one)):
    if list_one[j] == i and list_two[j] == "yes":
      tech += 1
  print i, ":", tech

The output of this code is:

con good : 3
tech : 3
finance : 3
retail : 2
M. Rie
  • 1
  • 2