Putting elements in lists

Asked

Viewed 94 times

3

I would like to have two lists: one with the name of the fruit and the other with the colors.

lista = ['banana [amarela]\n', 'uva [vinho]\n', 'laranja [laranjado]\n', 'kiwi [verde]\n', 'framboesa [vermelho]\n', 'coco [marrom]\n']

lines = lista.split(" ")

fruits = []
colors = []

for line in lines:
    fruits.append(line[0])
    #colors.append(line[1]) #IndexError: string index out of range

print(fruits)
#print(colors) #IndexError: string index out of range 

Script output:

['[', "'", 'b', 'a', 'n', 'a', 'a', 'n', 'a', '' '[', 'a', ’m', 'a', 'r', 'r', 'l', 'a', ']', '' ', 'n', "'"', ',' ', ''' ', 'u', 'v', 'i', 'n', 'h', 'o', ']', ', 'n', "'"'"', ',' ', 'a', 'a', 'n', 'j', a', ', 'a', ', 'a', ', 'a', ', 'a', ', 'a', ', 'a', ', ', 'a', 'a', ', 'a'[', 'l', 'a', 'r', 'a', 'n', 'j', 'a', '’d', 'o', '']', '''', 'n', "', ',' ', '"', 'k', 'i', 'w', 'i', '' ', 'i', ', '['v', 'e', '’d', 'e', ']', ', ''''', '"''''"''"', 'r', 'a', 'b', 'o', 'e', ', ', 'a', ', ', ''', ''[', ''', '''''', ''''', ''', ''''''[, 'v', ', 'r', ', ', ', ', ''', ''''', ', ', '', ', '''', ', ''', ', ', '', '''', ', ' "'", ',', ', '' ', '"'", 'c', 'o', 'c', 'o', '' ', '[', ’m', 'a', 'r', 'r', 'o', ’m', ']', ', ', 'n', "'", ']']

Desired exit:

Fruits = ['banana', 'grape', 'orange', 'kiwi', 'raspberry', 'coconut']

Colors = ['yellow', 'wine', 'orange', 'green', 'red', 'brown']

  • 1

    Are these values in a file? You are using the functions there read and readlines which appear to be a text file.

  • Oh yes, sorry. I am using these values in a file but I thought it would be easier to put the list here. I will edit my answer.

  • 1

    But in what format is each line in the file ? There is always only one fruit and one color per line ?

  • 1

    It gets easier, in fact, I just wanted to make sure I wasn’t using the functions inappropriately to read the values of a list.

  • Isac, exactly. One fruit and one color per line

4 answers

2


Breaking the content of the text in the white space does not seem to be a good solution, since there may be names of fruits and colors that have spaces, as for example fruta do conde [rosa choque] (Throw it away, it’s rotten!), or something like that. If the pattern is always fruta [cor], I believe it is more feasible to use a regular expression:

(.+) \[(.+)\]\n?
  1. (.+) creates a capture group for any string;
  2. White space indicating that the previous group must necessarily be followed by a space;
  3. \[(.+)\] creates another capture group for any string between brackets;
  4. \n? defines that the line may or may not end in a character \n;

In this way, the name of the fruit will match any sequence of characters, provided that it is followed by a blank space and some other sequence of characters between brackets, and may or may not be finished with the character \n. The first group will be the name of the fruit and the second group will be its color. In Python it would be:

import re

lista = ['banana [amarela]\n', 'uva [vinho]\n', 'laranja [laranjado]\n', 'kiwi [verde]\n', 'framboesa [vermelho]\n', 'coco [marrom]\n']

pattern = re.compile(r"(.+) \[(.+)\]\n?")

frutas = []
cores = []

for item in lista:
    if pattern.match(item):
        fruta, cor = pattern.search(item).groups()
        frutas.append(fruta)
        cores.append(cor)

print(frutas)
print(cores)

Producing the result:

['banana', 'uva', 'laranja', 'kiwi', 'framboesa', 'coco']
['amarela', 'vinho', 'laranjado', 'verde', 'vermelho', 'marrom']

See working on Ideone.

The function re.compile will generate a Python structure to handle the above regular expression. Then the list of items is traversed, and with the method pattern.match, checks whether the item content is compatible with the expected standard and, if so, extracts the values from the capture groups using the pattern.search. The method groups will return a tuple with the values of the capture groups, in this case a tuple of two values: the name of the fruit and its color. Thus, the technique of unpacking of tuple values in two variables:

fruta, cor = ("banana", "amarela")

Causing fruta receive banana and cor receive amarela, storing the values in the respective lists.

If these values are stored in a text file, you can do so:

import re

pattern = re.compile(r"(.+) \[(.+)\]\n?")

frutas = []
cores = []

with open("lista.txt") as file:
    for line in file:
        if pattern.match(line):
            fruta, cor = pattern.search(line).groups()
            frutas.append(fruta)
            cores.append(cor)

print(frutas)
print(cores)

See working on Repl.it.

1

If it is as constant as shown in your example you can do:

lista = ['banana [amarela]\n', 'uva [vinho]\n', 'laranja [laranjado]\n', 'kiwi [verde]\n', 'framboesa [vermelho]\n', 'coco [marrom]\n']
colors = []
fruits = []
for ele in lista:
    fruit, color = ele.strip().split(' ')
    colors.append(color[1:-1]) # retirar parentesis retos da cor
    fruits.append(fruit)

print(fruits) # ['banana', 'uva', 'laranja', 'kiwi', 'framboesa', 'coco']
print(colors) # ['amarela', 'vinho', 'laranjado', 'verde', 'vermelho', 'marrom']

DEMONSTRATION

1

It can be done as follows:

lista = ['banana [amarela]\n', 'uva [vinho]\n', 'laranja [laranjado]\n', 'kiwi [verde]\n', 'framboesa [vermelho]\n', 'coco [marrom]\n']

fruits, color = []

for element in lista:
    fc = element.split(" ")
    fruits += [fc[0]]
    color += [fc[1][1:-3]]

print "lista de frutas =" + str(fruits)
print "lista de cores =" + str(color)

1

>>> lista = ['banana [amarela]\n', 'uva [vinho]\n', 'laranja [laranjado]\n', 'kiwi [verde]\n', 'framboesa [vermelho]\n', 'coco [marrom]\n']
>>> l1, l2 = zip(*(l.strip().replace('[','').replace(']','').split() for l in lista))
>>> l1
('banana', 'uva', 'laranja', 'kiwi', 'framboesa', 'coco')
>>> l2
('amarela', 'vinho', 'laranjado', 'verde', 'vermelho', 'marrom')

Or if you need a list

>>> list(l1)
['banana', 'uva', 'laranja', 'kiwi', 'framboesa', 'coco']
>>> list(l2)
['amarela', 'vinho', 'laranjado', 'verde', 'vermelho', 'marrom']

Browser other questions tagged

You are not signed in. Login or sign up in order to post.