How to convert list of strings to integer indexes? - python-3.x

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]]

Related

Find the index location of an element in a Numpy array

If I have:
x = np.array(([1,4], [2,5], [2,6], [3,4], [3,6], [3,7], [4,3], [4,5], [5,2]))
for item in range(3):
choice = random.choice(x)
How can I get the index number of the random choice taken from the array?
I tried:
indexNum = np.where(x == choice)
print(indexNum[0])
But it didn't work.
I want the output, for example, to be something like:
chosenIndices = [1 5 8]
Another possibility is using np.where and np.intersect1d. Here random choice without repetition.
x = np.array(([1,4], [2,5], [2,6], [3,4], [3,6], [3,7], [4,3], [4,5], [5,2]))
res=[]
cont = 0
while cont<3:
choice = random.choice(x)
ind = np.intersect1d(np.where(choice[0]==x[:,0]),np.where(choice[1]==x[:,1]))[0]
if ind not in res:
res.append(ind)
cont+=1
print (res)
# Output [8, 1, 5]
You can achieve this by converting the numpy array to list of tuples and then apply the index function.
This would work:
import random
import numpy as np
chosenIndices = []
x = np.array(([1,4], [2,5], [2,6], [3,4], [3,6], [3,7], [4,3], [4,5], [5,2]))
x = x.T
x = list(zip(x[0],x[1]))
item = 0
while len(chosenIndices)!=3:
choice = random.choice(x)
indexNum = x.index(choice)
if indexNum in chosenIndices: # if index already exist, then it will rerun that particular iteration again.
item-=1
else:
chosenIndices.append(indexNum)
print(chosenIndices) # Thus all different results.
Output:
[1, 3, 2]

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

return dictionary of file names as keys and word lists with words unique to file as values

I am trying to write a function to extract only words unique to each key and list them in a dictionary output like {"key1": "unique words", "key2": "unique words", ... }. I start out with a dictionary. To test with I created a simple dictionary:
d = {1:["one", "two", "three"], 2:["two", "four",
"five"], 3:["one","four", "six"]}
My output should be:
{1:"three",
2:"five",
3:"six"}
I am thinking maybe split in to separate lists
def return_unique(dct):
Klist = list(dct.keys())
Vlist = list(dct.values())
aList = []
for i in range(len(Vlist)):
for j in Vlist[i]:
if
What I'm stuck on is how do I tell Python to do this: if Vlist[i][j] is not in the rest of Vlist then aList.append(Vlist[i][j]).
Thank you.
You can try something like this:
def return_unique(data):
all_values = []
for i in data.values(): # Get all values
all_values = all_values + i
unique_values = set([x for x in all_values if all_values.count(x) == 1]) # Values which are not duplicated
for key, value in data.items(): # For Python 3.x ( For Python 2.x -> data.iteritems())
for item in value: # Comparing values of two lists
for item1 in unique_values:
if item == item1:
data[key] = item
return data
d = {1:["one", "two", "three"], 2:["two", "four", "five"], 3:["one","four", "six"]}
print (return_unique(d))
result >> {1: 'three', 2: 'five', 3: 'six'}
Since a key may have more than one unique word associated with it, it makes sense for the values in the new dictionary to be a container type object to hold the unique words.
The set difference operator returns the difference between 2 sets:
>>> a = set([1, 2, 3])
>>> b = set([2, 4, 6])
>>> a - b
{1, 3}
We can use this to get the values unique to each key. Packaging these into a simple function yields:
def unique_words_dict(data):
res = {}
values = []
for k in data:
for g in data:
if g != k:
values += data[g]
res[k] = set(data[k]) - set(values)
values = []
return res
>>> d = {1:["one", "two", "three"],
2:["two", "four", "five"],
3:["one","four", "six"]}
>>> unique_words_dict(d)
{1: {'three'}, 2: {'five'}, 3: {'six'}}
If you only had to do this once, then you might be interested in the less efficeint but more consice dictionary comprehension:
>>> from functools import reduce
>>> {k: set(d[k]) - set(reduce(lambda a, b: a+b, [d[g] for g in d if g!=k], [])) for k in d}
{1: {'three'}, 2: {'five'}, 3: {'six'}}

Compare unique string values between two lists and get the count of matched values in python

I have two lists with some items in common and some not. I would like to compare the two lists and get the count of items that matched.
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
Pls advice how to do this in python
Use Counters and dictionary comprehension.
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
c1 = Counter(list1)
c2 = Counter(list2)
matching = {k: c1[k]+c2[k] for k in c1.keys() if k in c2}
print(matching)
print('{} items were in both lists'.format(len(macthing))
Output:
{'avocado': 2, 'orange': 2, 'tomato': 2, 'mango': 2, 'kiwi': 2}
5 items were in both lists
I think you can use set.intersection within a comprehension like this example:
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
result = {elm: list1.count(elm) + list2.count(elm) for elm in set.intersection(set(list1), set(list2))}
Output:
{'kiwi': 2, 'avocado': 2, 'orange': 2, 'tomato': 2, 'mango': 2}

Pythonic and secure way to convert a list of integers to a string and vis-à-vis

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."

Resources