Any reason not to convert string to list this way? - python-3.x

I'm using PyCharm on Windows (and very new to Python)
I'm a 'what happens when I try this?' person and so I tried:
alist = []
alist += 'wowser'
which returns ['w', 'o', 'w', 's', 'e', 'r']
Is there any reason not to convert a string to a list of individual characters like this? I know I could use For loop method OR I could .append or +concatenate (both seem to be too tedious!!), but I can't find anything that mentions using += to do this. So, since I'm new, I figure I should ask why not to do it this way before I develop a bad habit that will get me into trouble in the future.
Thanks for your help!

I think this would help: Why does += behave unexpectedly on lists?
About the question "Is there any reason not to convert a string to a list of individual characters like this". I think it depends on your purpose. It will be quite convenient if you need to split the letters. If you don't want to split the letters, just don't use it.

String is a type of array so it behaves like an array as lists do.
>>> # This way you would do it with a list:
>>> list('wowser')
['w', 'o', 'w', 's', 'e', 'r']
>>> lst=list('wowser')
>>> a='w'
>>> a is lst[0]
True
>>> # The String Version:
>>> strng = 'wowser'
>>> a is strng[0]
True
>>> # Iterate over the string like doing it with lists:
>>> [print(char) for char in 'wowser']
w
o
w
s
e
r
>>> [print(char) for char in ['w', 'o', 'w', 's', 'e', 'r']]
w
o
w
s
e
r
w3schools.com
docs.python.org

Related

Apparently empty groups generated with itertools.groupby

I have some troubles with groupby from itertools
from itertools import groupby
for k, grp in groupby("aahfffddssssnnb"):
print(k, list(grp), list(grp))
output is:
a ['a', 'a'] []
h ['h'] []
f ['f', 'f', 'f'] []
d ['d', 'd'] []
s ['s', 's', 's', 's'] []
n ['n', 'n'] []
b ['b'] []
It works as expected.
itertools._grouper objects seems to be readable only once (maybe iterators ?)
but:
li = [grp for k, grp in groupby("aahfffddssssnnb")]
list(li[0])
[]
list(li[1])
[]
It seems empty ... I don't understand why ?
This one works:
["".join(grp) for k, grp in groupby("aahfffddssssnnb")]
['aa', 'h', 'fff', 'dd', 'ssss', 'nn', 'b']
I am using version 3.9.9
Question already asked to newsgroup comp.lang.python without any answsers
grp is a sub-iterator over the same major iterator given to groupby. A new one is created for every key.
When you skip to the next key, the old grp is no longer available as you advanced the main iterator beyond the current group.
It is stated clearly in the Python documentation:
The returned group is itself an iterator that shares the underlying iterable with groupby(). Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be stored as a list:
k, g in groupby(data, keyfunc):
groups.append(list(g)) # Store group iterator as a list
uniquekeys.append(k)

Remove redundant sublists within list in python

Hello everyone I have a list of lists values such as :
list_of_values=[['A','B'],['A','B','C'],['D','E'],['A','C'],['I','J','K','L','M'],['J','M']]
and I would like to keep within that list, only the lists where I have the highest amount of values.
For instance in sublist1 : ['A','B'] A and B are also present in the sublist2 ['A','B','C'], so I remove the sublist1.
The same for sublist4.
the sublist6 is also removed because J and M were present in a the longer sublist5.
at the end I should get:
list_of_no_redundant_values=[['A','B','C'],['D','E'],['I','J','K','L','M']]
other exemple =
list_of_values=[['A','B'],['A','B','C'],['B','E'],['A','C'],['I','J','K','L','M'],['J','M']]
expected output :
[['A','B','C'],['B','E'],['I','J','K','L','M']]
Does someone have an idea ?
mylist=[['A','B'],['A','C'],['A','B','C'],['D','E'],['I','J','K','L','M'],['J','M']]
def remove_subsets(lists):
outlists = lists[:]
for s1 in lists:
for s2 in lists:
if set(s1).issubset(set(s2)) and (s1 is not s2):
outlists.remove(s1)
break
return outlists
print(remove_subsets(mylist))
This should result in [['A', 'B', 'C'], ['D', 'E'], ['I', 'J', 'K', 'L', 'M']]

Sliding Window algorithm in python 3.x. Extracting the before and after values of an element from a list

I have 2 lists; terms and key_terms. I need to extract the before and after elements from the terms list using the elements from the key_terms list. I have tried the below and it works but it has a bug.
terms=['b','a','f','s','w','c','g']
key_terms=['a','w','g']
context_terms=[]
for kt in key_terms:
if(kt!=0):
before=terms[(terms.index(kt))-1]
if(terms.index(kt)==len(terms)-1):
context_terms.append(before)
break
else:
after=terms[(terms.index(kt))+1]
context_terms.append(before)
context_terms.append(after)
print(context_terms)
Output: ['b', 'f', 's', 'c', 'c']
The problem with the above is that if the key_terms appear twice in the terms list, the second instance is ignored.
terms=['b','a','f','s','a','c','g']
key_terms=['a','g']
context_terms=[]
for kt in key_terms:
if(kt!=0):
before=terms[(terms.index(kt))-1]
if(terms.index(kt)==len(terms)-1):
context_terms.append(before)
break
else:
after=terms[(terms.index(kt))+1]
context_terms.append(before)
context_terms.append(after)
print(context_terms)
Output: ['b', 'f', 'c']
The correct output should be ['b', 'f', 's', 'c', 'c']
After some research i noticed that i have to use a sliding window. Can someone please help me because i can't understand how i am to apply the sliding window for my case. Thank you (P.s this is my first ever question, sorry if my issue is not clear)
Try looping over terms instead of key_terms. For every element in terms which is present in key_terms, add the element prior to and next to it.
The pseudo-code would be:
for e in terms:
if e present in key_terms:
ans.add(element_to_left_of_e)
ans.add(element_to_right_of_e)
As opposed to finding indices later, the following pseudo code might prove better to iterate over indices:
for index in range(0, length of terms):
if terms[index] present in key_terms:
ans.add(terms[index-1])
ans.add(terms[index+1])
If I get your problem correctly may be following can help:
terms=['b','a','f','s','a','c','g']
key_terms=['a','g']
context_terms=[]
for k in key_terms:
indices = [i for i, item in enumerate(terms) if item == k]
for kt in indices:
before=terms[kt - 1]
if kt == len(terms)-1:
context_terms.append(before)
break
else:
after=terms[kt + 1]
context_terms.append(before)
context_terms.append(after)
print(context_terms)
Output: ['b', 'f', 's', 'c', 'c']

How to create a matrix (5 x 5) with strings, without using numpy? (Python 3)

So I am creating a memory matching game, in which a player will pair two words from a list of words.
I am trying to create a 2D 5x5 matrix with strings without using numpy.
I've tried with for i in range(x): for j in range(x), but I can't get it to work.
So how do I do?
Python doesn't have a built in matrix type like that, but you can pretty much emulate it with a list of lists, or with a dict keyed by ordered pairs.
Here's the list of lists approach using a list comprehension inside a list comprehension:
from pprint import pprint
matrix = [[c for c in line] for line in '12345 abcde ABCDE vwxyz VWXYZ'.split()]
pprint(matrix)
The result, pretty-printed.
[['1', '2', '3', '4', '5'],
['a', 'b', 'c', 'd', 'e'],
['A', 'B', 'C', 'D', 'E'],
['v', 'w', 'x', 'y', 'z'],
['V', 'W', 'X', 'Y', 'Z']]
You can split on different characters in the inner or outer loops.
matrix = [[word for word in line.split()] for line in 'foo bar;spam eggs'.split(';')]
You get and set elements with a double lookup, like matrix[2][3].
Results can vary with pprint depending on the width of the words. List of lists are pretty easy to print in matrix form though. .join() is the inverse of .split().
print('\n'.join('\t'.join(line) for line in matrix))
And the result in this case,
foo bar
spam eggs
This just uses a tab character '\t', which may or may not produce good results depending on your tab stops and word withs. You can control this more precisely by using the justify string methods or .format() or f-strings with specifiers.
Here's one with the pair-keyed dict. Recall that tuples of hashable types are hashable too.
{(i, j): 'x' for i in range(5) for j in range(5)}
You get and set elements with a pair lookup, like matrix[2, 3].
Again, you can use words.
{(i, j): word
for i, line in enumerate("""\
1 2 3 4 5
foo bar baz quux norlf
FOO BAR BAZ QUUX NORLF
spam eggs sausage bacon ham
SPAM EGGS SAUSAGE BACON HAM""".split('\n'))
for j, word in enumerate(line.split())}

Is there any way to force ipython to interpret utf-8 symbols?

I'm using ipython notebook.
What I want to do is search a literal string for any spanish accented letters (ñ,á,é,í,ó,ú,Ñ,Á,É,Í,Ó,Ú) and change them to their closest representation in the english alphabet.
I decided to write down a simple function and give it a go:
def remove_accent(n):
listn = list(n)
for i in range(len(listn)):
if listn[i] == 'ó':
listn[i] =o
return listn
Seemed simple right simply compare if the accented character is there and change it to its closest representation so i went ahead and tested it getting the following output:
in []: remove_accent('whatever !## ó')
out[]: ['w',
'h',
'a',
't',
'e',
'v',
'e',
'r',
' ',
'!',
'#',
'#',
' ',
'\xc3',
'\xb3']
I've tried to change the default encoding from ASCII (I presume since i'm getting two positions for te accented character instead of one '\xc3','\xb3') to UTF-8 but this didnt work. what i would like to get is:
in []: remove_accent('whatever !## ó')
out[]: ['w',
'h',
'a',
't',
'e',
'v',
'e',
'r',
' ',
'!',
'#',
'#',
' ',
'o']
PD: this wouldn't be so bad if the accented character yielded just one position instead of two I would just require to change the if condition but I haven't find a way to do that either.
Your problem is that you are getting two characters for the 'ó' character instead of one. Therefore, try to change it to unicode first so that every character has the same length as follows:
def remove_accent(n):
n_unicode=unicode(n,"UTF-8")
listn = list(n_unicode)
for i in range(len(listn)):
if listn[i] == u'ó':
listn[i] = 'o'.encode('utf-8')
else:
listn[i]=listn[i].encode('utf-8')
return listn

Resources