Pythonic and secure way to convert a list of integers to a string and vis-à-vis - python-3.x

I have a list of integers (e. g. [1, 2, 3] and want to convert them to one string (e. g. "1, 2, 3"). Later I will convert the string back into a list of integers.
Is my solution pythonic enough or is there a much easier way?
# init values
int_list = [1, 2, 3]
# list of integers to string
string = str(int_list)[1:-1]
# string to list of integers
int_list = [int(i) for i in string.split(',')]
By the way: My first approach was to do exec("int_list = [" + str + "]"). But using exec is absolutly not recommended.

Use map:
a = [1, 2, 3]
b = list(map(str, a))
c = list(map(int, b))
EDIT: if you want only one string, then
a = [1, 2, 3]
b = ",".join(map(str, a))
c = list(map(int, b.split(",")))
EDIT2: you can also use this to convert the map to a list. I don't like it too much, but it's an option:
c = [*map(int, b.split(","))]

# to string
a = [1,2,3]
s = repr(a)
print(s)
# from string
import ast
print(ast.literal_eval(s))
Unlike eval, literal_eval "can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself."

Related

How to convert list of strings to integer indexes?

I have a list like this:
lst = [['ab', 'bc', 'cd'], ['dg', 'ab']]
I want to build a string indexer and convert it into:
lst_converted = [[1,2,3], [4,1]]
Do some processing on the converted list and then if the output is [[3], [2]]
lst_output = [['cd'], ['ab']]
Here,
'ab' = 1
'bc' = 2
'cd' = 3
'dg' = 4
Strings can be arbitrary and not necessarily characters. How to do this?
Use a list comprehension along with a dictionary to map the string literals to integer values:
d = {}
d['ab'] = 1
d['bc'] = 2
d['cd'] = 3
d['dg'] = 4
lst = [['ab', 'bc', 'cd'], ['dg', 'ab']]
lst_converted = [[d[y] for y in x] for x in lst]
print(lst_converted) # [[1, 2, 3], [4, 1]]

Make a list with non-decreasing order elements of a list in Python

I have a list a = [2,2,1,3,4,1] .
I want to make a new list c with the non-decreasing elements lists of list a.
That means my expected form is -
c = [[2,2],[1,3,4],[1]]
Here is my code:
>>> c = []
>>> for x in a:
... xx = a[0]
... if xx > x:
... b = a[:x]
... c.append(b)
... a = a[x:]
but my output is:
>>> c
[[2], [2]]
How can i make a list with all non-decreasing part of list a?
You can initialise the first entry of c with [a[0]] and then either append the current value from a to the end of the current list in c if it is >= the previous value, otherwise append a new list containing that value to c:
a = [2,2,1,3,4,1]
c = [[a[0]]]
last = a[0]
for x in a[1:]:
if x >= last:
c[-1].append(x)
else:
c.append([x])
last = x
print(c)
Output:
[[2, 2], [1, 3, 4], [1]]
If I understand what you are after correctly then what you want is to split the list every time the number decreases. If so then this should do what you need
c = []
previous_element = a[0]
sub_list = [previous_element]
for element in a[1:]:
if previous_element > element:
c.append(sub_list)
sub_list = []
previous_element = element
sub_list.append(previous_element)
c.append(sub_list)
Output:
In [1]: c
Out[2]: [[2, 2], [1, 3, 4], [1]]
There is possibly a clearer way to right the above, but it's pre coffee for me ;)
Also note that this code assumes that a will contain at least one item, if that is not always the case then you will need to either add an if statement around this, or re-structure the loop in a more while loop

How to multiply 2 input lists in python

Please help me understand how to code the following task in Python using input
Programming challenge description:
Write a short Python program that takes two arrays a and b of length n
storing int values, and returns the dot product of a and b. That is, it returns
an array c of length n such that c[i] = a[i] · b[i], for i = 0,...,n−1.
Test Input:
List1's input ==> 1 2 3
List2's input ==> 2 3 4
Expected Output: 2 6 12
Note that the dot product is defined in mathematics to be the sum of the elements of the vector c you want to build.
That said, here is a possibiliy using zip:
c = [x * y for x, y in zip(a, b)]
And the mathematical dot product would be:
sum(x * y for x, y in zip(a, b))
If the lists are read from the keyboard, they will be read as string, you have to convert them before applying the code above.
For instance:
a = [int(s) for s in input().split(",")]
b = [int(s) for s in input().split(",")]
c = [x * y for x, y in zip(a, b)]
Using for loops and appending
list_c = []
for a, b in zip(list_a, list_b):
list_c.append(a*b)
And now the same, but in the more compact list comprehension syntax
list_c = [a*b for a, b in zip(list_a, list_b)]
From iPython
>>> list_a = [1, 2, 3]
>>> list_b = [2, 3, 4]
>>> list_c = [a*b for a, b in zip(list_a, list_b)]
>>> list_c
[2, 6, 12]
The zip function packs the lists together, element-by-element:
>>> list(zip(list_a, list_b))
[(1, 2), (2, 3), (3, 4)]
And we use tuple unpacking to access the elements of each tuple.
From fetching the input and using map & lambda functions to provide the result. If you may want to print the result with spaces between (not as list), use the last line
list1, list2 = [], []
list1 = list(map(int, input().rstrip().split()))
list2 = list(map(int, input().rstrip().split()))
result_list = list(map(lambda x,y : x*y, list1, list2))
print(*result_list)
I came out with two solutions. Both or them are the ones that are expected in a Python introductory course:
#OPTION 1: We use the concatenation operator between lists.
def dot_product_noappend(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c = list_c + [list_a[i]*list_b[i]]
return list_c
print(dot_product_noappend([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
#OPTION 2: we use the append method
def dot_product_append(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c.append(list_a[i]*list_b[i])
return list_c
print(dot_product_append([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
Just note that the first method requires that you cast the product of integers to be a list before you can concatenate it to list_c. You do that by using braces ([[list_a[i]*list_b[i]] instead of list_a[i]*list_b[i]). Also note that braces are not necessary in the last method, because the append method does not require to pass a list as parameter.
I have added the two function calls with the values you provided, for you to see that it returns the correct result. Choose whatever function you like the most.

Python: How to find the average on each array in the list?

Lets say I have a list with three arrays as following:
[(1,2,0),(2,9,6),(2,3,6)]
Is it possible I get the average by diving each "slot" of the arrays in the list.
For example:
(1+2+2)/3, (2+0+9)/3, (0+6+6)/3
and make it become new arraylist with only 3 integers.
You can use zip to associate all of the elements in each of the interior tuples by index
tups = [(1,2,0),(2,9,6),(2,3,6)]
print([sum(x)/len(x) for x in zip(*tups)])
# [1.6666666666666667, 4.666666666666667, 4.0]
You can also do something like sum(x)//len(x) or round(sum(x)/len(x)) inside the list comprehension to get an integer.
Here are couple of ways you can do it.
data = [(1,2,0),(2,9,6),(2,3,6)]
avg_array = []
for tu in data:
avg_array.append(sum(tu)/len(tu))
print(avg_array)
using list comprehension
data = [(1,2,0),(2,9,6),(2,3,6)]
comp = [ sum(i)/len(i) for i in data]
print(comp)
Can be achieved by doing something like this.
Create an empty array. Loop through your current array and use the sum and len functions to calculate averages. Then append the average to your new array.
array = [(1,2,0),(2,9,6),(2,3,6)]
arraynew = []
for i in range(0,len(array)):
arraynew.append(sum(array[i]) / len(array[i]))
print arraynew
As you were told in the comments with sum and len it's pretty easy.
But in python I would do something like this, assuming you want to maintain decimal precision:
list = [(1, 2, 0), (2, 9, 6), (2, 3, 6)]
res = map(lambda l: round(float(sum(l)) / len(l), 2), list)
Output:
[1.0, 5.67, 3.67]
But as you said you wanted 3 ints in your question, would be like this:
res = map(lambda l: sum(l) / len(l), list)
Output:
[1, 5, 3]
Edit:
To sum the same index of each tuple, the most elegant method is the solution provided by #PatrickHaugh.
On the other hand, if you are not fond of list comprehensions and some built in functions as zip is, here's a little longer and less elegant version using a for loop:
arr = []
for i in range(0, len(list)):
arr.append(sum(l[i] for l in list) / len(list))
print(arr)
Output:
[1, 4, 4]

How to turn a string lists into a lists?

There are other threads about turning strings inside a lists into different data types. I want to turn a string that is in the form of a lists into a lists. Like this: "[5,1,4,1]" = [5,1,4,1]
I need this because I am writing a program that requires the user to input a lists
Example of problem:
>>> x = input()
[3,4,1,5]
>>> x
'[3,4,1,5]'
>>> type(x)
<class 'str'>
If you mean evaluate python objects like this:
x = eval('[3,4,1,5]');
print (x);
print(type(x) is list)
[3, 4, 1, 5]
True
Use this with caution as it can execute anything user will input. Better use a parser to get native lists. Use JSON for input and parse it.
Use eval() for your purpose. eval() is used for converting code within a string to real code:
>>> mystring = '[3, 5, 1, 2, 3]'
>>> mylist = eval(mystring)
>>> mylist
[3, 5, 1, 2, 3]
>>> mystring = '{4: "hello", 2:"bye"}'
>>> eval(mystring)[4]
'hello'
>>>
Use exec() to actually run functions:
>>> while True:
... inp = raw_input('Enter your input: ')
... exec(inp)
...
Enter your input: print 'hello'
hello
Enter your input: x = 1
Enter your input: print x
1
Enter your input: import math
Enter your input: print math.sqrt(4)
2.0
In your scenario:
>>> x = input()
[3,4,1,5]
>>> x = eval(x)
>>> x
[3, 4, 1, 5]
>>> type(x)
<type 'list'>
>>>
Thanks for your input guys, but I would prefer not to eval() because it is unsafe.
Someone actually posted the answer that allowed me to solve this but then they deleted it. I am going to reposts that answer:
values = input("Enter values as lists here")
l1 = json.loads(values)
You can use ast.literal_eval for this purpose.
Safely evaluate an expression node or a string containing a Python
expression. The string or node provided may only consist of the
following Python literal structures: strings, bytes, numbers, tuples,
lists, dicts, sets, booleans, and None.
This can be used for safely evaluating strings containing Python
expressions from untrusted sources without the need to parse the
values oneself.
>>> import ast
>>> val = ast.literal_eval('[1,2,3]')
>>> val
[1, 2, 3]
Just remember to check that it's actually a list:
>>> isinstance(val, list)
True

Resources