How to read excel cell values as a list? - python

When I tried to read data from excel file (excell sheet screenshot attached), I get values as strings. But i need python datatype when i read excel file data.
#read excel file
dataframe1 = pd.read_excel('Data.xlsx')
Below code line give me list of string that makes sense.
#read mega_links column
mega_linkss = dataframe1.iloc[:,7].tolist()
for link in mega_linkss:
print(link, ' ',type(link))
break
OUTPUT:
"['https://mega.nz/folder/KXICCZrS#dJT2bqTh3eK_xbbMPuNglQ']" <class 'str'>
As you can see class is 'str'
To get class as 'list', i tried following code.
# when i used list function to convert string in list.
for link in mega_linkss:
print(list(link))
break
OUTPUT:
['[', "'", 'h', 't', 't', 'p', 's', ':', '/', '/', 'm', 'e', 'g', 'a', '.', 'n', 'z', '/', 'f', 'o', 'l', 'd', 'e', 'r', '/', 'K', 'X', 'I', 'C', 'C', 'Z', 'r', 'S', '#', 'd', 'J', 'T', '2', 'b', 'q', 'T', 'h', '3', 'e', 'K', '_', 'x', 'b', 'b', 'M', 'P', 'u', 'N', 'g', 'l', 'Q', "'", ']']
I need output like this.
OUTPUT:
['https://mega.nz/folder/KXICCZrS#dJT2bqTh3eK_xbbMPuNglQ'] <class 'list'>
Excell Sheet Screenshot is attached.
Code Screenshot is attached for a better understanding of what I need.
Thanks
[enter image description here](https://i.stack.imgur.com/yLsK8.jpg)
I need output like this.
OUTPUT:
['https://mega.nz/folder/KXICCZrS#dJT2bqTh3eK_xbbMPuNglQ'] <class 'list'>

The value in your excel file is a string "['https...']". It is a string representation of a list, so if you wanted to convert it to a list, you could use eval(string) or ast.literal_eval(string).
eval is considered unsafe, and ast.literal_eval is a safer alternative, part of a built-in ast module.
For example, ast.literal_eval("[1,2,3]") = [1, 2, 3]. Likewise, ast.literal_eval(link) will return a list version of your link, which according to your excel table will be a list with a single string in it.

Related

Python: How to replace string elements using an array of tuples?

I'm trying to replace the characters of the reversed alphabet with those of the alphabet. This is what I've got:
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
rev_alphabet = alphabet[::-1]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
def f(alph, rev_alph):
return (alph, rev_alph)
char_list_of_tups = list(map(f, alphabet, rev_alphabet))
for alph, rev_alph in char_list_of_tups:
sample = sample.replace(rev_alph, alph)
print(sample)
expected output: did you see last night's episode?
actual output: wrw you svv ozst nrtst's vprsowv?
I understand that I'm printing the last "replacement" of the whole iteration. How can I avoid this without appending it to a list and then running into problems with the spacing of the words?
Your problem here is that you lose data as you perform each replacement; for a simple example, consider an input of "az". On the first replacement pass, you replace 'z' with 'a', and now have "aa". When you get to replacing 'a' with 'z', it becomes "zz", because you can't tell the difference between an already replaced character and one that's still unchanged.
For single character replacements, you want to use the str.translate method (and the not strictly required, but useful helper function, str.maketrans), to do character by character transliteration across the string in a single pass.
from string import ascii_lowercase # No need to define the alphabet; Python provides it
# You can use the original str form, no list needed
# Do this once up front, and reuse it for as many translate calls as you like
trans_map = str.maketrans(ascii_lowercase[::-1], ascii_lowercase)
sample = sample.translate(trans_map)
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
# or
alphabet = [chr(97 + i) for i in range(0,26)]
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
res = []
for ch in sample:
if ch in alphabet:
res.append(alphabet[-1 - alphabet.index(ch)])
else:
res.append(ch)
print("".join(res))
Another Way if you are ok with creating a new string instead.
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
dictRev = dict(zip(alphabet, alphabet[::-1]))
sample = "wrw blf hvv ozhg mrtsg'h vkrhlwv?"
s1="".join([dictRev.get(char, char) for char in sample])
print(s1)
"did you see last night's episode?"

Python join string elements in separate lists then add lists together

If I have two lists of individual string characters:
['H', 'e', 'l', 'l', 'o']
['w', 'o', 'r', 'l', 'd']
How do I make the final outcome look like this below of one list and where all of the string characters are combined:
['Hello','world']
If I try something like this:
word1join = "".join(word1)
word2join = "".join(word2)
print(word1join,type(word1join))
print(word2join,type(word1join))
print(list(word1join + word2join))
I am recreating the original data structure again but incorrectly, any tips appreciated!
Hello <class 'str'>
world <class 'str'>
['H', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
Just create a new list with them in:
word1 = ['H', 'e', 'l', 'l', 'o']
word2 = ['w', 'o', 'r', 'l', 'd']
word1join = "".join(word1)
word2join = "".join(word2)
print([word1join, word2join])
Output as requested
If your variable names have numbers in them, it's usually a good hint that you should better be manipulating one list, rather than several individual variables.
Instead of starting with two variables:
word1 = ['H', 'e', 'l', 'l', 'o']
word2 = ['w', 'o', 'r', 'l', 'd']
Start with one list:
words = [['H', 'e', 'l', 'l', 'o'], ['w', 'o', 'r', 'l', 'd']]
You can still access individual words using indexing:
print(words[1])
# ['H', 'e', 'l', 'l', 'o']
You can then apply operations to every element of that list using for-loops, or list comprehensions, or function map:
words_joined = [''.join(word) for word in words]
# ['Hello', 'world']
# OR ALTERNATIVELY
words_joined = list(map(''.join, words))
# ['Hello', 'world']
If you really need to split the list into two variables, you can still do it:
word1joined, word2joined = words_joined
print(word2joined)
# world

How to create a dictionary from two lists of different sizes?

I have a list of symbols:
symbols_list = ['*','†','‡','§','¶','#']
and a longer list of elements as:
note_list = ['a','b','c','d'.....'z']
I want to join them in a dictionary to look like this:
{'*':'a','†':'b','‡':'c','§':'d','¶':'e','#':'f','**':'g','††':'h'...'***':'m'...etc. }
so basically the symbols_list values would repeat as *, **, ***, **** etc.
I tried to just get the symbols_list to be the same length at first using:
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a])
but it ended up doubling the elements each iteration instead of just adding one character each time
['*',
'†',
'‡',
'§',
'¶',
'#',
'**',
'††',
'‡‡',
'§§',
'¶¶',
'##',
'****',
'††††',
'‡‡‡‡',
'§§§§',
'¶¶¶¶',
'####',
'********',
'††††††††',
'‡‡‡‡‡‡‡‡',
'§§§§§§§§',
'¶¶¶¶¶¶¶¶',
'########',
'****************']
I thought it would be easier to make the symbols_list the same size first, and then combine them into a dictionary.
I couldn't resist trying to do it with itertools.
from itertools import chain, count
# yields *, †, ... **, ††, ... infinitely
symbol_generator = chain.from_iterable(((i*x for x in symbols_list) for i in count(1)))
{s:c for s,c in zip(symbol_generator, abc)}
{'*': 'a',
'†': 'b',
'‡': 'c',
'§': 'd',
'¶': 'e',
'#': 'f',
'**': 'g',
'††': 'h',
'‡‡': 'i',
'§§': 'j',
'¶¶': 'k',
'##': 'l',
'***': 'm',
'†††': 'n',
'‡‡‡': 'o',
'§§§': 'p',
'¶¶¶': 'q',
'###': 'r',
'****': 's',
'††††': 't',
'‡‡‡‡': 'u',
'§§§§': 'v',
'¶¶¶¶': 'w',
'####': 'x',
'*****': 'y',
'†††††': 'z'}
Maybe do it like this:
new_symbols_list = []
for i in range(len(note_list)//len(symbols_list)+1):
new_symbols_list += [k*(i+1) for k in symbols_list]
output = {s: l for s, l in zip(new_symbols_list[:len(note_list)], note_list)}
>>> output
{'*': 'a',
'†': 'b',
'‡': 'c',
'§': 'd',
'¶': 'e',
'#': 'f',
'**': 'g',
'††': 'h',
'‡‡': 'i',
'§§': 'j',
'¶¶': 'k',
'##': 'l',
'***': 'm',
'†††': 'n',
'‡‡‡': 'o',
'§§§': 'p',
'¶¶¶': 'q',
'###': 'r',
'****': 's',
'††††': 't',
'‡‡‡‡': 'u',
'§§§§': 'v',
'¶¶¶¶': 'w',
'####': 'x',
'*****': 'y',
'†††††': 'z'}
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a])
You append symbols_list[a]+symbols_list[a], which essentially doubles symbols_list[a]. You just want to add the first character of symbols_list[a] to itself, so do
for a in range(0,math.ceil(len(note_list)/len(symbols_list))):
symbols_list.append(symbols_list[a]+symbols_list[a][0])
Here is a oneliner:
{ (int(i/len(symbols_list))+1)*symbols_list[i%len(symbols_list)] : e for i, e in enumerate(note_list) }

How can I convert strings from a text file into matrix (python)

For example:
content of myfile has
fsdfasf
frjfmcd
39djaxs
I want to convert this in to a matrix where it consists of
my_matrix=[['f','s','d','f','a','s','f'],['f','r','j'......]]
I've tried reading the file using
for line in file:
line = line.strip('\n)
print(line)
But it's not giving me the desired output.
What am I missing to do?
You need to turn your string into a list to get the output you want. Since strings are sequences, when you pass a string to list() if breaks it up into individual characters:
with open(path) as file:
matrix = [list(line.strip()) for line in file]
matrix:
[['f', 's', 'd', 'f', 'a', 's', 'f'],
['f', 'r', 'j', 'f', 'm', 'c', 'd'],
['3', '9', 'd', 'j', 'a', 'x', 's']]

Conditional statement does not work when appending a list relative to another

I am trying to remove certain characters from a string. My way of going about it is to turn the string into a list, iterate through each list and append each good character to a new list and return that new list but for some reason, it doesn't do that. This is the input:
"4193 with words"
and this is the output:
4193withwords
In other words, the only part of the code which works is the part of removing the whitespaces. Here is my entire code:
class Solution:
def myAtoi(self, str: str) -> int:
illegal_char = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '#', '#', '$', '%', '^', '&' '*', '(', ')', '=', '+', '[', ']', '{', '}', '|']
new_list = []
integer_list = list(str)
for i in range(len(integer_list)):
if integer_list[i] != any(illegal_char):
new_list.append(integer_list[i])
output = ''.join(new_list)
output = output.replace(' ', '')
return output
You can do a join on a list-comprehension. What you need is a membership check in list and form string with only those characters you need:
''.join([x for x in s if x not in illegal_char]).replace(' ', '')
Note that I have renamed your string to s, because str is a built-in.
Also to add, if you can include space as illegal_char you can avoid replace at the end.
Hmm, this is a very complicated way of replacing some characters. I suggest you, to learn some regex, as it could help you alot. There is a regex library for python called re.
This would be my solution:
import re
mytext = "4193 with words"
newtext = re.sub("\s", "", mytext)

Categories