简体   繁体   中英

iterating over a list searching for certein elements python

i have a list that looks like this:

Lprices=["a","b","c","500 $",d,e,....]

i want to create a list that include only the prices in the Lprices list. the logic behind Lprices is that it includes 3 word elements, and then a price, and again, 3 word elements and a price. problem is, sometimes there is no price after the 3 word elements, so there's a 6 or 9 word elements in a row before the next price: example:

Lprices=["a","b","c","d","e","f",500$]

so i wrote a code, it's not very pythonic, more stright forward from my C++ university course

prices = []
i=0
count=0
for price in Lprices:
    count=count+1
    if '₪' in price:
        if (count+i)%4==0:
            prices.append(price)
        else:
            i=i+1
            prices.append("No Price")
            prices.append(price)

EDIT: the output should be like this:

prices=["price1","price2","No Price","price4"]

means i need to know if there wasn't a price.

the problem with this code is that it deals only in the option of 1 missing price every time and not more, and also, it's not at all pythonic.

2nd EDIT: this is the raw data:

[a,a,a,4$,b,b,b,5$,c,c,c,d,d,d,2$,r,r,r,f,f,f,g,g,g,3$...] goes on like this for around 200 elements

is there a way to improve it?

This will simple check if the 4th list item exists and is a price. If yes, we have at the beginning 3 words + price; else only 3 words and no price. The test is then repeated for the rest of the list.

NOPRICE = "no price"
def prices(lst):
    while lst:
        try:
            p = lst[3]
        except IndexError:
            yield NOPRICE
            break
        if '$' in p:  # improve the price test if necessary
            yield p
            lst = lst[4:]
        else:
            yield NOPRICE
            lst = lst[3:]


Lprices=["a","b","c","d","e","f","500$"]
print(list(prices(Lprices)))

There may be better ways of doing it, but I thought of doing it extensively by list comprehensions to give it a Pythonic feeling. Also, you can reduce the number of list comprehensions but then it will be become unreadable.

import itertools
Lprices = ["a","b","c","500 $","d","e","f", "g","h", "i", "600 $"]

price_list = [list(x[1]) for x in itertools.groupby(Lprices, lambda x: "$" in x)]
print(price_list)
# [['a', 'b', 'c'], ['500 $'], ['d', 'e', 'f', 'g', 'h', 'i'], ['600 $']]
# Above step clusters in sub-lists those with '$' symbol and no '$' symbol.

price_list = [price if len(price) == 1 else ['No price'] * ((len(price) - 3) // 3) for price in price_list]
print(price_list)
# [[], ['500 $'], ['No price'], ['600 $']] Notice empty array
# Above step replaces non $ symbols with No-price list. 
# If contains only 3 elements, no substitution will take place.

price_list = [item for sublist in price_list for item in sublist]
print(price_list)
# ['500 $', 'No price', '600 $']

You will have to read documentation of groupby for better understanding of it.

Hope the answer helps you.

  • Poping 3 elements and checking 4 element.
  • If 4th value is price, then pop it and append to val list also otherwise continue.

Code:

Lprices=['a','a','a','4$','b','b','b','5$','c','c','c','d','d','d','2$','r','r','r','f','f','f','g','g','g','3$']

a = True
val =  []
list_zero = False
i = 0
while True:
    for i in range(3):
        if len(Lprices) != 0:
            Lprices.pop(0)
        else:
            list_zero = True
            break

    if list_zero is False:

        if '$' in Lprices[0]:
            val.append(Lprices[0])
            Lprices.pop(0)
        else:
            val.append('No Price')
    else:
        break

print val

Output

C:\Program Files (x86)\Python27> python demo.py
['4$', '5$', 'No Price', '2$', 'No Price', 'No Price', '3$']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM