0

I have 2 lists:

my_values = ['0,78', '0,40', '0,67']

my_list = [
    ['Morocco', 'Meat', '190,00', '0,15'], 
    ['Morocco', 'Meat', '189,90', '0,32'], 
    ['Morocco', 'Meat', '189,38', '0,44'],
    ['Morocco', 'Meat', '188,94', '0,60'],
    ['Morocco', 'Meat', '188,49', '0,78'],
    ['Morocco', 'Meat', '187,99', '0,101'],
    ['Spain', 'Meat', '190,76', '0,10'], 
    ['Spain', 'Meat', '190,16', '0,20'], 
    ['Spain', 'Meat', '189,56', '0,35'],
    ['Spain', 'Meat', '189,01', '0,40'],
    ['Spain', 'Meat', '188,13', '0,75'],
    ['Spain', 'Meat', '187,95', '0,78'],
    ['Italy', 'Meat', '190,20', '0,11'],
    ['Italy', 'Meat', '190,10', '0,31'], 
    ['Italy', 'Meat', '189,32', '0,45'],
    ['Italy', 'Meat', '188,61', '0,67'],
    ['Italy', 'Meat', '188,01', '0,72'],
    ['Italy', 'Meat', '187,36', '0,80'],
]

I have a code which is checking the following:

  1. For Morocco it checks at what index[2] inmy_listisindex[3]in my_values == 0,78
  2. For Spain it checks at what index[2] inmy_list isindex[3]in my_values == 0,40
  3. For Italy it checks at what index[2] in my_list isindex[3]in my_values == 0,67

Now I have a problem, as you can see 0,78 in my_values is present in Morocco AND Spain, I only want it to check it for Morocco.

This is my code:

yet_another_list = [i[2] for i in my_list if i[3] in my_values]
print(yet_another_list)

This is my output:

['188,49', '189,01', '187,95', '188,61']

This is my prefered output:

['188,49', '189,01', '188,61']

As you can see I want index[1] of my_values to be only used for Morocco, and index[2] for Spain etc... Please note that in my officla dataset my_lists contains a lot more countries...

#ADDED. I even tried Pandas but still received the same output.

df=pd.DataFrame(my_list)
df['Filter']=np.where([i in my_values for i in df[3]],"Yes","")
my_out_list=list(df[2][df['Filter']=='Yes'])

print(my_out_list)

>> 
['188,49', '189,01', '187,95', '188,61']
3
  • You are misusing a value as unique identifier that is not a unique identifier. Commented Jan 4, 2021 at 10:16
  • When someone leaves a comment instead of an answer, it usually means they do not have a complete solution. Maybe review the help center to better understand how this site works. Commented Jan 4, 2021 at 10:20
  • Switching to Pandas but copying the same bug obviously doesn't solve the problem, though it will probably scale handsomely. Commented Jan 4, 2021 at 10:27

3 Answers 3

1

Using original data structures with iterators.

def get_values(my_list_, *my_values_):
    ''' Finds the desired result using my_list_ and my_values
        my_valuesis one or more list
    '''
    output = []
    # Find values for each list in my_values_
    for my_values__ in my_values_:
         # Create iterators 
        result = []
        my_values_iter = iter(my_values__) # iterator for current list of values
        my_list_iter = iter(my_list_)  # from beginning of my_list_

        v = next(my_values_iter, None)
        i = next(my_list_iter, None)
        while v and i:
            if v == i[3]:
                # found match
                result.append(i[2])
                v = next(my_values_iter, None) # Next value to find in my_values
                i = next(my_list_iter, None)   # Next value to check in my_list
            else:
                # try next value from my_list
                i = next(my_list_iter, None)   # Next value to check in my_list
        output.append(result)
        
     if len(output) == 1:
        return output[0]  # Only single list
    else:
        return tuple(x for x in output) # Output tuple of lists
    

Usage

# Single list of values
a = get_values(my_list, ['0,78', '0,40', '0,67'])
print(f'a = {a}') # Output: a = ['188,49', '189,01', '188,61']

# Two list of values (can handle an arbitrary number)
a, b = get_values(my_list, ['0,78', '0,40', '0,67'], ['0,78', '0,10', '0,78'])
print(f'a = {a}, b = {b}') # Output: a = ['188,49', '189,01', '188,61'], b = ['188,49', '190,76', '187,95']
Sign up to request clarification or add additional context in comments.

8 Comments

@DarryIG, this seems a good one. Cant it be any shorter though? I have another addition though. What if I had another extra list named my_values_2 with also 3 values inside of it. I can copy paste the code, but I prefer doing it all in once...
@TanGerCity--meaning you want the resultant list from my_values_1 and my_values_2. Does my_values_2 start check my_list from the beginning or does it continue from where my_values_1 left off in my_list?
@DarryIG, it starts from the beginning again. It actually is the same thing again just different values inside my_values_2
@TangerCity--updated to handle 1 or more list of values.
@DarryIG but that means I should have 2 output lists as well.....
|
1

I'd recommend using a dictionary and then filtering your dataset

my_values = {'Morocco': '0,78', 'Spain': '0,40', 'Italy': '0,67'}

my_list = [
    ['Morocco', 'Meat', '190,00', '0,15'], 
    ['Morocco', 'Meat', '189,90', '0,32'], 
    ['Morocco', 'Meat', '189,38', '0,44'],
    ['Morocco', 'Meat', '188,94', '0,60'],
    ['Morocco', 'Meat', '188,49', '0,78'],
    ['Morocco', 'Meat', '187,99', '0,101'],
    ['Spain', 'Meat', '190,76', '0,10'], 
    ['Spain', 'Meat', '190,16', '0,20'], 
    ['Spain', 'Meat', '189,56', '0,35'],
    ['Spain', 'Meat', '189,01', '0,40'],
    ['Spain', 'Meat', '188,13', '0,75'],
    ['Spain', 'Meat', '187,95', '0,78'],
    ['Italy', 'Meat', '190,20', '0,11'],
    ['Italy', 'Meat', '190,10', '0,31'], 
    ['Italy', 'Meat', '189,32', '0,45'],
    ['Italy', 'Meat', '188,61', '0,67'],
    ['Italy', 'Meat', '188,01', '0,72'],
    ['Italy', 'Meat', '187,36', '0,80'],
]


print([e[2] for e in filter(lambda x: x[3] == my_values[x[0]], my_list)])

>>> ['188,49', '189,01', '188,61']

As a side note, if you're working with much larger data sets it might be beneficial to look at the pandas package, a popular Python library for data analysis

5 Comments

I understand your answer but it doesnt solve my much bigger dataset. Do you know how to solve this with Pandas?
Why do you think this doesn't work for a bigger data set?
@tripleee because I manually need to fix my_values.
That doesn't make this a bad answer. Your current data structure is cumbersome and will probably introduce additional problems down the line.
Ok, then using pandas won't really solve that problem. If the order of cities in my_list matches the order of the values in my_values then you could make use of that with some extra processing.
0

If I understand your requirement correctly, you want to loop over countries in the list, and simultaneously loop over the indices in the other list?

previous = my_list[0][0]
ind = 0
result = []
for item in my_list:
    if item[0] != previous:
        ind += 1
        previous = item[0]
    if item[3] == my_values[ind]:
        result.append(item[2])
print(result)

This will obviously throw an IndexError if you have more countries than values in my_values.

Perhaps a better approach would be to turn my_list into a dict where the keys are country names and the values are the values for that country, though.

2 Comments

your answer says index out of range. I even tried pandas but still received the same output.
Try now; I forgot to update the previous variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.