How to insert quotes in list to separate items? - python

NEW QUESTION:
So I have the list a:
a = ["abcd"]
but I want it to be:
a = ["a","b","c","d"]
The list I'm working with is very long (200 terms long; not 4)
So how do I make Python put a quote (") after each letter so they're individual terms? Because I don't want to manually do this for all my lists.

In [4]: a = ["abcd"]
In [5]: list(a[0])
Out[5]: ['a', 'b', 'c', 'd']
For previous version:
In [3]: a = ["a,b,c,d"]
In [4]: a[0].split(",")
Out[4]: ['a', 'b', 'c', 'd']

#Akavall's answer is very good, but in case you are dealing with a list with possible whitespace around the commas like this:
my_list = ["a, b, c, d"]
You'll want to strip the resulting items like so:
new_list = [x.strip() for x in my_list.split(',')]
For a list like this:
my_list = ["abcd"]
you'll need a different approach. Just do:
new_list = list(a[0])

Related

How to remove apostrophes from a list in python?

I need to remove apostrophes -> ' <- from a list, within python, without using any add-ons, so only built in functions.
E.g. I need a list like:
lista = ['a', 'b', 'c', 'd']
into
lista = [ a, b, c, d]
I've tried using for with .replace or making the list into a string then replacing, but I haven't had anything work yet.
Any chance you could help?
You can use str.join() to concatenate strings with a specified separator.
For example:
>>> strings = ['A', 'B', 'C']
>>> print(', '.join(strings))
A, B, C
Furthermore, in your case, str.format() may also help:
>>> strings = ['A', 'B', 'C']
>>> print('strings = [{}]'.format(', '.join(strings)))
strings = [A, B, C]
You cannot remove apostrophes from a list because that's pretty much how you identify what a list is. However the apostrophes will not interfere with anything you do with the list. The apostrophes show that the elements are strings.

Splitting string values in list into individual values, Python

I have a list of values in which some values are words separated by commas, but are considered single strings as shown:
l = ["a",
"b,c",
"d,e,f"]
#end result should be
#new_list = ['a','b','c','d','e','f']
I want to split those strings and was wondering if there's a one liner or something short to do such a mutation. So far what, I was thinking of just iterating through l and .split(',')-ing all the elements then merging, but that seems like it would take a while to run.
import itertools
new_list = list(itertools.chain(*[x.split(',') for x in l]))
print(new_list)
>>> ['a', 'b', 'c', 'd', 'e', 'f']
Kind of unusual but you could join all your elements with , and then split them:
l = ["a",
"b,c",
"d,e,f"]
newList = ','.join(l).split(',')
print(newList)
Output:
['a', 'b', 'c', 'd', 'e', 'f']
Here's a one-liner using a (nested) list comprehension:
new_list = [item for csv in l for item in csv.split(',')]
See it run here.
Not exactly a one-liner, but 2 lines:
>>> l = ["a",
"b,c",
"d,e,f"]
>>> ll =[]
>>> [ll.extend(x.split(',')) for x in l]
[None, None, None]
>>> ll
['a', 'b', 'c', 'd', 'e', 'f']
The accumulator needs to be created separately since x.split(',') can not be unpacked inside a comprehension.

Converting all letters in a document from one list to another in Python

I have two lists
list1 = ['a', 'b', 'c']
list2 = ['d', 'e', 'f']
I have a variable with random text in it.
var = 'backout'
I want to convert all letters in the variable that exist in list1 to the letters in list2.
expectedOutput = 'edfkout'
Is there a way to do this?
You want to use str.translate using a translation table from string.maketrans (This is str.maketrans in Python 3)
from string import maketrans
s1 = 'abc'
s2 = 'def'
table = maketrans(s1, s2)
print('backout'.translate(table))
Edit:
Note that we have to use strings instead of lists as our arguments to maketrans.
We can map the keys to values using a zip()wrapped with dict() and then iterate the letters and map them to their corresponding ones with themselves being the default (in case not found):
keys = ['a', 'b', 'c']
values = ['d', 'e', 'f']
mapper = dict(zip(keys, values))
var = 'backout'
output = "".join([mapper.get(k, k) for k in var])
print(output) # edfkout
Convert each char to its ascii value using map(ord,list1) and do the 1-1 mapping b/w list1 and list2 using zip
tbl = dict(zip(map(ord,list1), map(ord,list2)))
var.translate(tbl)
Output:
edfkout
For people who prefer shorter but more complicated solution (instead of using the translate() method), here it is:
list1 = ['a', 'b', 'c']
list2 = ['d', 'e', 'f']
var = 'backout'
trans_dict = dict(zip(list1, list2))
out_string = ''.join([trans_dict.get(ch, ch) for ch in var])
The explanation:
dict(zip(list1, list2))
creates the {'a': 'd', 'b': 'e', 'c': 'f'} dictionary.
trans_dict.get(ch, ch)
The 1st argument is a key - if it is found in keys, we obtain its value: trans_dict[ch]
The 2nd argument is a default value - used if the first argument is not found in keys. We obtain ch.
[trans_dict.get(ch, ch) for ch in var]
is a list comprehension - something as creating a list from the empty list, appending next and next element in the for loop.
''.join(list_of_string)
is a standard way for concatenating individual elements of the list (in our case, the individual characters).
(Instead of the empty string there may be an arbitrary string - it is used for delimiting individual elements in the concatenated string)

Access list elements that are not equal to a specific value

I am searching through a list like this:
my_list = [['a','b'],['b','c'],['a','x'],['f','r']]
and I want to see which elements come with 'a'. So first I have to find lists in which 'a' occurs. Then get access to the other element of the list. I do this by abs(pair.index('a')-1)
for pair in my_list:
if 'a' in pair:
print( pair[abs(pair.index('a')-1)] )
Is there any better pythonic way to do that?
Something like: pair.index(not 'a') maybe?
UPDATE:
Maybe it is good to point out that 'a' is not necessarily the first element.
in my case, ['a','a'] doesn't happen, but generally maybe it's good to choose a solution which handles this situation too
Are you looking for elements that accompany a? If so, a simple list comprehension will do:
In [110]: [x for x in my_list if 'a' in x]
Out[110]: [['a', 'b'], ['a', 'x']]
If you just want the elements and not the pairs, how about getting rid of a before printing:
In [112]: [(set(x) - {'a'}).pop() for x in my_list if 'a' in x]
Out[112]: ['b', 'x']
I use a set because a could either be the first or second element in the pair.
If I understand your question correctly, the following should work:
my_list = filter(
lambda e: 'a' not in e,
my_list
)
Note that in python 3, this returns a filter object instance. You may want to wrap the code in a list() command to get a list instance instead.
That technique works ok here, but it may be more efficient, and slightly more readable, to do it using sets. Here's one way to do that.
def paired_with(seq, ch):
chset = set(ch)
return [(set(pair) - chset).pop() for pair in seq if ch in pair]
my_list = [['a','b'], ['b','c'], ['x','a'], ['f','r']]
print(paired_with(my_list, 'a'))
output
['b', 'x']
If you want to do lots of tests on the same list, it would be more efficient to build a list of sets.
def paired_with(seq, ch):
chset = set(ch)
return [(pair - chset).pop() for pair in seq if ch in pair]
my_list = [['a','b'], ['b','c'], ['x','a'], ['f','r']]
my_sets = [set(u) for u in my_list]
print(my_sets)
print(paired_with(my_sets, 'a'))
output
[{'b', 'a'}, {'c', 'b'}, {'x', 'a'}, {'r', 'f'}]
['b', 'x']
This will fail if there's a pair like ['a', 'a'], but we can easily fix that:
def paired_with(seq, ch):
chset = set(ch)
return [(pair - chset or chset).pop() for pair in seq if ch in pair]
my_list = [['a','b'], ['b','c'], ['x','a'], ['f','r'], ['a', 'a']]
my_sets = [set(u) for u in my_list]
print(paired_with(my_sets, 'a'))
output
['b', 'x', 'a']

Python list comprehension does not seem to work

I am trying to implement a list comprehension for a for loop-nested if code block. However, what seems to work using the conventional nested form does not seem to work in its list comprehension representation. From what I could see after spending a considerable amount of time is that it follows the logic as required. Please let me know if there is anything else I am skipping.
for x in data_list:
if x not in encoding:
encoding.append(x)
Using list comprehension
encoding = [x for x in data_list if x not in encoding]
Thank you.
Your issue is here:
encoding = [x for x in data_list if x not in encoding]
What you are doing is you are reassigning encoding to this list comprehension [x for x in data_list if x not in encoding].
So what you're doing is setting encoding to be only the elements that weren't in it in the first place.
What you should do is this:
encoding.extend([x for x in data_list if x not in encoding])
In this way, you're extending the list with the results of the list comprehension.
Here's some test code:
encoding = ['a','b','c','d']
encoding2 = ['a','b','c','d']
data_list = ['a','b','c','d','d','d','e','f','g']
print(encoding)
print(encoding2)
for x in data_list:
if x not in encoding:
encoding.append(x)
encoding2.extend([x for x in data_list if x not in encoding2])
print(encoding)
print(encoding2)
which prints:
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
Now, this is not a perfect solution, as it will still duplicate elements if they're in data_list more than once. The reason for this is that in the for loop example, encoding is checked after each append operation whereas the list comprehension operates only based on encoding's initial state. So it will push elements into it more than once if they're in data_list more than once.
If you want to get around this, convert the list comprehension to a set first as follows:
encoding.extend(set([x for x in data_list if x not in encoding]))
There you have it!
Your two examples are not equivalent. If you want to append elements from data_list to encoding that are not already in encoding (which is what your for-loop example does), but using list-comprehension, do:
encoding.extend(x for x in data_list if x not in encoding)
[x for x in data_list if x not in encoding] executes on 'one breath', so it doesn't update encoding on the run, resulting in empty encoding that leads to every item being selected.
Use list(set(data_list)) to do what you are trying to achieve. That will convert the list to set, resulting in loss of duplicates, then convert it back to list.
>>> a = [1, 2, 3, 2, 3]
>>> list(set(a))
[1, 2, 3]
>>> a = [1, 4, 2, 5, 'g', 'd', 'g', 2, 4]
>>> list(set(a))
[1, 2, 'd', 4, 5, 'g']
If you already have data in encoding, you can simply add it:
list(set([x for x in data_list if x not in encoding]))
The 2 encoding's in your list comprehension are not the same variable. If you must have an one liner, reduce is more appropriate:
encoding = reduce(lambda l,x: x in l and l or l+[x], data_list, encoding)
although I don't think it's very readable.

Categories