-1

the code should do this but it is still printing some without 4 letters

def friend(x):
    global a
    a = 0
    global friends
    for friends in x:
        global b
        b = 0
        for letter in x[a]:
            b += 1
        if b != 4:
            x.remove(x[a])
        if b == 4:
            a += 1
    print(x)
ab = ["jim", "john", "jack", "jeff", "fuasadfa", "fgadkljbg"]
friend(ab)
  • Welcome to Stack Overflow. I can't understand the question. Given that `ab = ["jim", "john", "jack", "jeff", "fuasadfa", "fgadkljbg"]`, **exactly** what **should** the output be? – Karl Knechtel Dec 14 '21 at 07:30
  • all this "global" stuff ist just a silly way to count the amount of letters in a word. why at all do you need a and b to be global ? why is friends global? you never use any of them outside the scope of your function - hint: NOT global at all. Then you remove somthing from the list you are just iterating over which is never to be done - hence the "is still printing some without 4 letters" Problem. See dupe for why. – Patrick Artner Dec 14 '21 at 07:32

3 Answers3

1

If all you want is a new list where all members are 4 letters long, it's just this:

def friend(x):
    return [x1 for x1 in x if len(x1) == 4]
ab = ["jim", "john", "jack", "jeff", "fuasadfa", "fgadkljbg"]
print(friend(ab))

If you don't like the list comprehension:

def friend(x):
    out = []
    for name in x:
        if len(name) == 4:
            out.append(name)
    return out

ab = ["jim", "john", "jack", "jeff", "fuasadfa", "fgadkljbg"]
print(friend(ab))
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
1

You could alternatively use filter:

list(filter(lambda x:len(x)==4, ab))

even if, you need to get a list back, it is better to use the list comprehension given that it is faster. If you can keep the filter object because you need an iterable to work with later on, then the filter option is faster. The time difference can be dramatic if the list is very big, in my experience.

To put it in numbers - say that you define a list abc which is abc = ab * 10000 (hence, 60k elements):

from timeit import timeit

>>> timeit(lambda:[x for x in abc if len(x) == 4], number=10_000)
32.38528540000004
>>> timeit(lambda:list(filter(lambda x:len(x) == 4, abc)), number=10_000)
59.476141900000016
>>> timeit(lambda:filter(lambda x:len(x) == 4, abc), number=10_000)
0.002855100000033417
nikeros
  • 3,302
  • 2
  • 10
  • 26
0

The problem you have that you have not removed some names which is not at length 4 is because of your condition of adding to a. If you do some counting you'll see that after the "jeff" your a will be = 2. By that definition you will remove "jeff" from the list while still having the 2 names of more characters still in the list when you have iterated "fuasadfa". I guess you still have the last name in the list when this function has run.

Other than that you have a few troubles in you implementation. I'd argue that you do not want to change your list that you are iterating while inside a for loop. This is because the foor-loop is in charge of the iteration, if you want to have more control over the iteration try a while-loop instead. (the line x.remove(x[a]) is what i'm refering to). This is most likely also what's causing your troubles as you have implemented an own count function to check the length of the string.

The use of global variables is not needed in this case as you are only within one function scope and will not be using the variables as you set them to globals (that you can reach from anywhere in the program).

If you want another implementation from your own look above of length of strings and create a new list rather than changin the one you are iterating, or use a while loop!

Albin Sidås
  • 321
  • 2
  • 10