Converting String list to pure list in Python - python

I have a string type list from bash which looks like this:
inp = "["one","two","three","four","five"]"
The input is coming from bash script.
In my python script I would like to convert this to normal python list in this format:
["one","two","three","four","five"]
where all elements would be string, but the whole thin is represented as list.
I tried: list(inp)
it does not work. Any suggestions?

Try this code,
import ast
inp = '["one","two","three","four","five"]'
ast.literal_eval(inp) # will prints ['one', 'two', 'three', 'four', 'five']

Have a look at ast.literal_eval:
>>> import ast
>>> inp = '["one","two","three","four","five"]'
>>> converted_inp = ast.literal_eval(inp)
>>> type(converted_inp)
<class 'list'>
>>> print(converted_inp)
['one', 'two', 'three', 'four', 'five']
Notice that your original input string is not a valid python string, since it ends after "[".
>>> inp = "["one","two","three","four","five"]"
SyntaxError: invalid syntax

The solution using re.sub() and str.split() functions:
import re
inp = '["one","two","three","four","five"]'
l = re.sub(r'["\]\[]', '', inp).split(',')
print(l)
The output:
['one', 'two', 'three', 'four', 'five']

you can use replace and split as the following:
>>> inp
"['one','two','three','four','five']"
>>> inp.replace('[','').replace(']','').replace('\'','').split(',')
['one', 'two', 'three', 'four', 'five']

Related

How to filter list items based on regex in python?

I have two list items and I want to generate a list based on non-matching items. Here is what I am trying to do:
from __future__ import print_function
import os
mainline_list = ['one', 'two', 'three', 'four']
non_main_list = ['two', 'seven', 'six', 'four', 'four-3.1', 'new_three']
itemized_list = [item for item in non_main_list if item not in mainline_list]
print(itemized_list)
What is returns is
['seven', 'six', 'four-3.1', 'new_three']
while what I want is:
['seven', 'six']
Regex is not necessary, you can use all() builtin function:
mainline_list = ['one', 'two', 'three', 'four']
non_main_list = ['two', 'seven', 'six', 'four', 'four-3.1', 'new_three']
print([item for item in non_main_list if all(i not in item for i in mainline_list)])
Prints:
['seven', 'six']

lambda in lambda

Can anybody explain me whats wrong i am doing here -
multiArray = [
['one', 'two', 'three', 'four', 'five'],
['one', 'two', 'three', 'four', 'five'],
['one', 'two', 'three', 'four', 'five']
]
search ='four'
p1 = list(filter(lambda outerEle: search == outerEle, multiArray[0]))
p = list(filter(lambda multiArrayEle: list(filter(lambda innerArrayEle: search == innerArrayEle, multiArrayEle)), multiArray))
print (p1)
print (p)
The result i am getting here is
['four']
[['one', 'two', 'three', 'four', 'five'], ['one', 'two', 'three', 'four', 'five'], ['one', 'two', 'three', 'four', 'five']]
while i am expecting
[['four'],['four'],['four']]
In your second filter, you are using a list as a predicate (as opposed to simply a bool as you do in the first filter); now, this implicitly applies the built-in method bool to each element list, and for a list l, bool(l) is true exactly when l is non-empty:
In [4]: bool([])
Out[4]: False
In [5]: bool(['a'])
Out[5]: True
This allows you to pick out, for example, all the non-empty lists in a list of lists:
In [6]: ls = [['a'], [], ['b']]
In [7]: list(filter(lambda l: l, ls))
Out[7]: [['a'], ['b']]
Thus, in your case, at the end of the day, your filter ends up giving you all lists for which 'four' appears, which is all of them.
From your given example, it's not immediately obvious what you are trying to achieve as all the inputs are identical, but my guess is that it's something like the following:
In [19]: multiArray = [
...: ['one', 'two', 'three', 'four', 'five', 'four'],
...: ['one', 'two', 'three', 'for', 'five'],
...: ['one', 'two', 'three', 'four', 'five']
...: ]
In [20]: [list(filter(lambda x: x == search, l)) for l in multiArray]
Out[20]: [['four', 'four'], [], ['four']]
While #fuglede's answer is really the answer to your question, you can archive the result you want by changing your outer filter to map:
p = list(map(lambda multiArrayEle: list(filter(lambda innerArrayEle: search == innerArrayEle, multiArrayEle)), multiArray))

List all elements, but only one of duplicated elements?

Say I have a list of strings such as
words = ['one', 'two', 'one', 'three', 'three']
I want to create a new list in alphabetical order like
newList = ['one', 'three', 'two']
Anyone have any solutions? I have seen suggestions that output duplicates, but I cannot figure out how to achieve this particular goal (or maybe I just can't figure out how to google well.)
Throw the contents into a set to remove duplicates and sort:
newList = sorted(set(words))
OR maybe this, using set:
newList=sorted({*words})
If Order of elements in words is important for you. You can try this.
from collections import OrderedDict
words = ['one', 'two', 'one', 'three', 'three']
w1 = OrderedDict()
for i in words:
if i in w1:
w1[i]+=1
else:
w1[i] = 1
print(w1.keys())

Substitutions with elements from a list with re.sub?

What is the best way to perform substitutions with re.sub given a list? For example:
import re
some_text = 'xxxxxxx#yyyyyyyyy#zzzzzzzzz#'
substitutions = ['ONE', 'TWO', 'THREE']
x = re.sub('#', lambda i: i[0] substitutions.pop(0), some_text) # this doesn't actually work
The desired output would be:
some_text = 'xxxxxxxONEyyyyyyyyyTWOzzzzzzzzzTHREE'
You just have a syntax error in your lambda:
>>> substitutions = ['ONE', 'TWO', 'THREE']
>>> re.sub('#', lambda _: substitutions.pop(0), some_text)
'xxxxxxxONEyyyyyyyyyTWOzzzzzzzzzTHREE'
If you don't want to modify the list, you can wrap it an iterable.
>>> substitutions = ['ONE', 'TWO', 'THREE']
>>> subs = iter(substitutions)
>>> re.sub('#', lambda _: next(subs), some_text)
'xxxxxxxONEyyyyyyyyyTWOzzzzzzzzzTHREE'
One way (there's probably a better one, I don't really know Python) is to compile the regular expression, then use that sub instead:
import re
some_text = 'xxxxxxx#yyyyyyyyy#zzzzzzzzz#'
substitutions = ['ONE', 'TWO', 'THREE']
pattern = re.compile('#')
x = pattern.sub(lambda i: substitutions.pop(0), some_text)
Here's a demo.
The code is almost correct, it needs a slight correction of a syntax error:
import re
some_text = 'xxxxxxx#yyyyyyyyy#zzzzzzzzz#'
substitutions = ['ONE', 'TWO', 'THREE']
x = re.sub('#', lambda i: substitutions.pop(0), some_text) # the error was in the lambda function

Python split '123' into '1', '2', '3'

My program takes a user input such as:
>>> x = input()
>>> 1
>>> print x
>>> one
my actual code:
>>> import string
>>> numbers = ['0','1','2','3','4','5','6','7','8','9']
>>> wordNumbers = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
>>> myDict = dict(zip(numbers, wordNumbers))
>>> myVar = (raw_input("Enter a number to be tranlated: "))
>>> for translate in myVar.split():
>>> print(myDict[translate])
The problem is I need the user to input 123 and for my program to output one two three, but it doesn't for some reason.
I'm thinking that if I add spaces with some syntax between 123 like 1 2 3 it would work.
You simply need to use:
for translate in myVar:
Instead of:
for translate in myVar.split():
Iterating over a string gives you its characters one by one, which is what you need.
If you do want to convert '123' to '1 2 3' (which isn't needed here because you don't need to use split), you can use:
' '.join(myVar)

Categories