Python Forum
Slicing Python list of strings into individual characters
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Slicing Python list of strings into individual characters
#1
I’m trying to get slice a list of strings into individual characters ...but using slicing.

Here is my list:

first_list = ["apples", "bananas", "oranges",]
Here is the end result and what I am trying to achieve:

['a', 'p', 'p', 'l', 'e', 's', 'b', 'a', 'n', 'a', 'n', 'a', 's', 'o', 'r', 'a', 'n', 'g', 'e', 's']
I succeeded using a for loop:

for item in first_list:
   for character in item:
       second_list.append(character)
print(second_list)
That’s a basic for loop which I completely understand the syntax and logic.

But I am now trying to come up with an alternate solution this time using slicing. Here is my valiant attempt:

print(third_list.append(first_list[:][:]))
My interpreter prints ‘None’ with that code. I am not sure why. Could someone explain?

My humble lucid, cerebral explanation for that one-liner is: Python is printing the third_list variable which is a composition of each letter (appended together) contained in first_list. I’m obviously mistaken because the result is just None. Could someone please correct my explanation here?

I suppose a further and more important question that I have is this: Who among you could perform the same for loop operation that worked the first time but instead using two slices (as I have awkwardly attempted but failed to do)?
Reply
#2
?
sum(map(list, first_list), [])
Reply
#3
(Apr-15-2019, 02:35 AM)Drone4four Wrote:
for item in first_list:
   for character in item:
       second_list.append(character)
print(second_list)
That’s a basic for loop which I completely understand the syntax and logic.

If you completely understand syntax and logic of this you should move to next level - list comprehension. Same result with less code:

>>> [character for item in first_list for character in item]
Is there any particular reason you want to use slicing?

(Apr-15-2019, 02:35 AM)Drone4four Wrote:
print(third_list.append(first_list[:][:]))
My interpreter prints ‘None’ with that code. I am not sure why. Could someone explain?

List method .append changed third_list in-place and returned None (all Python function/methods return/yield value or None). If you want to see what happened you should print out third_list not the result of the method.

Some exaples:

>>> def do_nothing():
...     pass
...
>>> do_nothing()         # nothing happens
>>> print(do_nothing())
None                     # function returns None
>>> def say_hello():
...     print('Hello')
...
>>> say_hello()
Hello
>>> print(say_hello())
Hello                    # functions prints
None                     # function returns None as there is no return (or yield)
>>> def return_five():
...     return 5
...
>>> return_five():
5
>>> print(return_five())
5                        
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#4
To understand scidam's solution, you need knowledge about the sum function and __add__ operation of lists.
In addition the sum function is supplied with an initial value.
The map function takes the first element, which is a string.
The map function calls list with the string-element.
The sum function takes this element and adds it to the initial value, which is a list.


first_list = ["apples", "bananas", "oranges",]
sum(map(list, first_list), [])
A more naive solution is this:
first_list = ["apples", "bananas", "oranges",]
concatenated_str = first_list[0] + first_list[1] + first_list[2]
flat_list = list(concatenated_str) # turns the string into a list
Another solution can be found in the module itertools.

from itertools import chain


first_list = ["apples", "bananas", "oranges",]
flat_list = chain.from_iterable(first_list)
print(flat_list)
Output:
<itertools.chain at 0x7f0857c921d0>
Until now this piece of code has not done much. You need to iterate over the object, to get all elements out.
The benefit is, that you can decide if you want to have a tuple, list, set or something else.

Consume the iterator:
solution = list(flat_list)
print(solution)
# this does not work!
# print(list(flat_list))
# flat_list is already exhausted and does not start from the beginning
# this is why i assigned the result to solution
Another solution can be yield from.

def flatten(iterable):
    for element in iterable:
        yield from element
This generator goes 2 levels deep. First it iterates over iterable, then the element you got is the string.
This string is iterated by yield from. If you write this less dense, it looks like this:


def flatten(iterable):
    for element in iterable:
        for char in element:
            yield char
This function is used, like the other generators. (Generators are lazy evaluated).

print(list(flatten(first_list)))
Output:
['a', 'p', 'p', 'l', 'e', 's', 'b', 'a', 'n', 'a', 'n', 'a', 's', 'o', 'r', 'a', 'n', 'g', 'e', 's']
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#5
Thank you @scidam, @perfringo, @DeaD_EyE for your helpful replies.

There is a lot here. I’ve reviewed all of your posts a few times and have played around with different combinations with all of your code samples in my Python interpreter.

For now I am going share some things I learned from exploring @DeaD_EyE’s use of the chain function from the itertools library. When you first shared the chain function, you used this:

from itertools import chain

first_list = ["apples", "bananas", "oranges",]
flat_list = chain.from_iterable(first_list)
print(flat_list)
I didn’t really understand how or why that code worked. So I found the official Python doc for the function. From this doc:

Quote:Alternate constructor for chain(). Gets chained inputs from a single iterable argument that is evaluated lazily. Roughly equivalent to:
def from_iterable(iterables):
    # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
    for it in iterables:
        for element in it:
            yield element

This sparse explanation went over my head, in part because the Python docs are written by programmers for programmers. So I continued reading your post, @DeaD_EyE and you basically re-phrased the method using your own language:

Quote:This generator goes 2 levels deep. First it iterates over iterable, then the element you got is the string.
This string is iterated by yield from.

I find this to be a clearer explanation of the process. Thank you.

I still had to look up the yield keyword for functions. Check out this SO post titled, “What does the “yield” keyword do?”. From there I learned that yield is similar to return but for generators where an iterable is only iterated over once.

I’m not sure I understand what you mean when you say “consume the iterator”. You explained that print(list(flat_list)) wouldn’t work because the last was supposed to be already exhausted. But I entered each line into my Python interpreter and there was no traceback or issue presented. It turns out there was no need to assign the result to the solution after all. See attached for an image of my interpreter. @DeaD_EyE: What could you (or anyone else reading this) make of this?

Attached Files

Thumbnail(s)
   
Reply
#6
(Apr-17-2019, 12:35 AM)Drone4four Wrote: I’m not sure I understand what you mean when you say “consume the iterator”. You explained that print(list(flat_list)) wouldn’t work because the last was supposed to be already exhausted. But I entered each line into my Python interpreter and there was no traceback or issue presented.

There is subtle difference in here:

In [8]: from itertools import chain                                                                                             

In [9]: flat_list = chain.from_iterable(['apples', 'bananas', 'oranges'])                                                       

In [10]: print(flat_list)                    # printing out object, not consuming iterator                                                                                
<itertools.chain object at 0x10cd56048>       

In [11]: list(flat_list)                     # consuming iterator i.e. iterating over and creating list                                                                                  
Out[11]: 
['a', /../  's']

In [12]: list(flat_list)                     # consuming exhausted iterator                                                                                                                 
Out[12]: []

(Apr-15-2019, 02:35 AM)Drone4four Wrote: I’m trying to get slice a list of strings into individual characters ...but using slicing.

I observed that there is no answer to original question. I have no idea why would anyone want to do it as there are built-in tools for that. However, following silly code uses slicing as aftertought to get list of individual characters:

 
>>> lst = ['apples', 'bananas', 'oranges']
>>> [fruit[i:i+1] for fruit in lst for i in range(len(fruit))]
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to read module/class from list of strings? popular_dog 1 424 Oct-04-2023, 03:08 PM
Last Post: deanhystad
  Trying to understand strings and lists of strings Konstantin23 2 699 Aug-06-2023, 11:42 AM
Last Post: deanhystad
  problem in using int() with a list of strings akbarza 4 647 Jul-19-2023, 06:46 PM
Last Post: deanhystad
  Delete strings from a list to create a new only number list Dvdscot 8 1,466 May-01-2023, 09:06 PM
Last Post: deanhystad
  Help with Logical error processing List of strings dmc8300 3 1,033 Nov-27-2022, 04:10 PM
Last Post: Larz60+
  How to expand and collapse individual parts of the code in Atom Lora 2 1,104 Oct-06-2022, 07:32 AM
Last Post: Lora
  Splitting strings in list of strings jesse68 3 1,703 Mar-02-2022, 05:15 PM
Last Post: DeaD_EyE
  Extract continuous numeric characters from a string in Python Robotguy 2 2,583 Jan-16-2021, 12:44 AM
Last Post: snippsat
  Python win32api keybd_event: How do I input a string of characters? JaneTan 3 3,727 Oct-19-2020, 04:16 AM
Last Post: deanhystad
  slicing and indexing a list example leodavinci1990 4 2,286 Oct-12-2020, 06:39 AM
Last Post: bowlofred

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020