0

I have a list which contains multimple lists inside it and it looks like this:

my_list = [
    ['Morocco', 'Fish', '0,012'], 
    ['Morocco', 'Fish', '0,153'], 
    ['Morocco', 'Fish', '0,114'],
    ['Morocco', 'Fish', '0,109'],
    ['Morocco', 'Fish', '0,252'],
    ['Spain', 'Fish', '0,012'], 
    ['Spain', 'Fish', '0,113'], 
    ['Spain', 'Fish', '0,116'],
    ['Spain', 'Fish', '0,250'],
    ['Spain', 'Fish', '0,266'],
    ['Italy', 'Fish', '0,112'], 
    ['Italy', 'Fish', '0,025'], 
    ['Italy', 'Fish', '0,224'],
    ['Italy', 'Fish', '0,256'],
    ['Italy', 'Fish', '0,245']]

And I have a variable which looks like this:

my_limit = 0.2

Now for every list I want to get the last value before it exceeds my_limit. I want that value to be stored in a new variable.

This is what I tried:

for l in my_list:
    if row[-1]  #<-- this is actually where I block.... I dont know how to fix it.

This is the output I expect:

0,109
0,116
0,025
wjandrea
  • 28,235
  • 9
  • 60
  • 81
TangerCity
  • 775
  • 2
  • 7
  • 13
  • 1
    See [this answer](https://stackoverflow.com/a/6633912/4518341) for how to do locale-aware number conversion. – wjandrea Dec 14 '20 at 14:46
  • @wjandrea that answer is confusing me. I dont need to converse any numbers....or converse a string with a float..... – TangerCity Dec 14 '20 at 14:50
  • @TangerCity You do need as the numbers in your array have a comma `'0,012'`. – Marco Dec 14 '20 at 14:51
  • Yes you do... You need to get values like `'0,012'` into floats, and the builtin won't do it: `float('0,012')` -> `ValueError: could not convert string to float: '0,012'` – wjandrea Dec 14 '20 at 14:51
  • 1
    Oke but converting them to floats is just halve of the problem is it? – TangerCity Dec 14 '20 at 14:53
  • @Tanger Yes, exactly, that's why I left a comment instead of an answer. – wjandrea Dec 14 '20 at 14:57
  • What result do you expect for a sequence like `"0,110", "0,256", "0,196"` with a limit of `0.2`? Just to double-check whether you want a position-based result or a value-based one. – Mike Roll Dec 14 '20 at 15:19

2 Answers2

2

It's simply a matter of iterating over the list and reporting list[n-1] when list[n]>my_limit.

You will need to extend this to cope with edge cases (i.e. this will error if the first value is over the limit etc.)

And you might want to split your list into one list per commodity as this will trigger when commodities change too.

my_limit = 0.2

for n in range(1, len(my_list)):
    value = float(my_list[n][2].replace(",", "."))
    prev_value = float(my_list[n-1][2].replace(",", "."))

    if value > my_limit and prev_value < my_limit:
        print(my_list[n-1])
JeffUK
  • 4,107
  • 2
  • 20
  • 34
1

you can use the itertools module for this

>>> import itertools
>>> my_list = [
    ['Morocco', 'Fish', '0,012'],
    ['Morocco', 'Fish', '0,153'],
    ['Morocco', 'Fish', '0,114'],
    ['Morocco', 'Fish', '0,109'],
    ['Morocco', 'Fish', '0,252'],
    ['Spain', 'Fish', '0,012'],
    ['Spain', 'Fish', '0,113'],
    ['Spain', 'Fish', '0,116'],
    ['Spain', 'Fish', '0,250'],
    ['Spain', 'Fish', '0,266'],
    ['Italy', 'Fish', '0,112'],
    ['Italy', 'Fish', '0,025'],
    ['Italy', 'Fish', '0,224'],
    ['Italy', 'Fish', '0,256'],
    ['Italy', 'Fish', '0,245']]
>>> my_limit = 0.2
>>> for key,sublists in itertools.groupby(my_list,lambda y:y[0]):
        v=[] #we initialize it in case no element fulfill the condition
        for v in itertools.takewhile(lambda x:float(x[-1].replace(",","."))<my_limit ,sublists):
            pass
        if v: 
            print(v,"->",v[-1])

    
['Morocco', 'Fish', '0,109'] -> 0,109
['Spain', 'Fish', '0,116'] -> 0,116
['Italy', 'Fish', '0,025'] -> 0,025
>>> 

here with groupby we, well, group together all the consecutive sublist that have the same value in a given position we specify, which in this case is the first position, then we go into those sublist and take those that fulfill our condition and stop at the first that doesn't with takewhile and from those we only want the last one which will stored into v at the end of the loop.

I make that grouping because that make more sense to my, but if grouping like that isn't necessary, we can also use groupby to split the list into the subsection that fulfill the condition and those that do not by changing the grouping key

>>> my_list = [
    ['Morocco', 'Fish', '0,012'],
    ['Morocco', 'Fish', '0,153'],
    ['Morocco', 'Fish', '0,114'],
    ['Morocco', 'Fish', '0,109'],
    ['Morocco', 'Fish', '0,252'],
    ['Morocco', 'Fish', '0,002'],#extra
    ['Morocco', 'Fish', '0,252'],#extra
    ['Spain', 'Fish', '0,012'],
    ['Spain', 'Fish', '0,113'],
    ['Spain', 'Fish', '0,116'],
    ['Spain', 'Fish', '0,250'],
    ['Spain', 'Fish', '0,266'],
    ['Spain', 'Fish', '0,066'], #extra
    ['Spain', 'Fish', '0,366'], #extra
    ['Italy', 'Fish', '0,112'],
    ['Italy', 'Fish', '0,025'],
    ['Italy', 'Fish', '0,224'],
    ['Italy', 'Fish', '0,256'],
    ['Italy', 'Fish', '0,245'],
    ['Italy', 'Fish', '0,005'],#extra
    ['Italy', 'Fish', '0,305']]#extra
>>> for condition,sublist in itertools.groupby(my_list,lambda x:float(x[-1].replace(",","."))<my_limit):
        if condition:
            for v in sublist:
                pass
            print(v,"->",v[-1])

        
['Morocco', 'Fish', '0,109'] -> 0,109
['Morocco', 'Fish', '0,002'] -> 0,002
['Spain', 'Fish', '0,116'] -> 0,116
['Spain', 'Fish', '0,066'] -> 0,066
['Italy', 'Fish', '0,025'] -> 0,025
['Italy', 'Fish', '0,005'] -> 0,005
>>>    
Copperfield
  • 8,131
  • 3
  • 23
  • 29