2

I'm writing a function that needs to go through a list of lists, collect all letters uppercase or lowercase and then return a list with 1 of each letter that it found in order. If the letter appears multiple times in the list of lists the function only has to report the first time it sees the letter.

For example, if the list of lists was [['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']] then the function output should return ["M","N","g","B"].

The code I have so far seems like it could work but it doesn't seem to be working. Any help is appreciated

def get_symbols(lot):

    symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

    newlot = []

    for i in lot:
        if i == symbols:
            newlot.append(symbols)
            return newlot
        else:
            return None
beeftendon
  • 876
  • 7
  • 14
warrior4223
  • 113
  • 1
  • 1
  • 8

3 Answers3

3

To build on your existing code:

import string

def get_symbols(lot):
    symbols = string.ascii_lowercase + string.ascii_uppercase
    newlot = []

    for sublot in lot:
        for x in sublot:
            if x in symbols and x not in newlot:
                newlot.append(x)

    return newlot

print get_symbols([['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']])

Using string gets us the letters a little more neatly. We then loop over each list provided (each sublot of the lot), and then for each element (x), we check if it is both in our list of all letters and not in our list of found letters. If this is the case, we add it to our output.

asongtoruin
  • 9,794
  • 3
  • 36
  • 47
1

There are a few things wrong with your code. You are using return in the wrong place, looping only over the outer list (not over the items in the sublists) and you were appending symbols to newlot instead of the matched item.

def get_symbols(lot):

    symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' # You should define this OUTSIDE of the function

    newlot = []

    for i in lot: # You are iterating over the outer list only here
        if i == symbols: # == does not check if an item is in a list, use `in` here
            newlot.append(symbols) # You are appending symbols which is the alphabet
            return newlot # This will cause your function to exit as soon as the first iteration is over
        else:
            return None # No need for this

You can use a double for loop and use in to check if the character is in symbols and isn't already in newlot:

l = [['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']]
symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

def get_symbols(lot):

    newlot = []

    for sublist in lot:
        for i in sublist:

            if i in symbols and i not in newlot:
                newlot.append(i)

    return newlot

This is the output for your list:

>>> get_symbols(l)
['M', 'N', 'g', 'B']
Farhan.K
  • 3,425
  • 2
  • 15
  • 26
0

this also can be done by using chain, OrderedDict and isalpha as follow

>>> from collections import OrderedDict
>>> from itertools import chain
>>> data = [['.', 'M', 'M', 'N', 'N'],['.', '.', '.', '.', 'g'], ['B', 'B', 'B', '.','g']]
>>> temp = OrderedDict.fromkeys(chain.from_iterable(data))
>>> [x for x in temp if x.isalpha()]
['M', 'N', 'g', 'B']
>>> 

chain.from_iterable will serve the same purpose as if you concatenate all the sublist in one

As the order is relevant, OrderedDict will server the same purpose as an set by removing duplicates with the added bonus of preserving the order of the first instance of the object added. The fromkeys class-method will create a dictionary with the given keys and same value, which by default is None, and as we don't care about it, for our purpose is a orderer set

Finally the isalpha will tell you if the string is a letter or not

you can also take a look at the unique_everseen recipe, because itertools is your best friend I recommend to put all those recipes in a file that is always at hand, they always are helpful

Copperfield
  • 8,131
  • 3
  • 23
  • 29