Recreate the code without list comprehension - python-3.x

I am learning about list comprehension therefore i would like to recreate the code without list comprehension.
The code is the following:
items=[x for x in input().split(",")]
items.sort()
print (items)
This is how i recreated it:
print ("Enter comma seperated words: ")
userinput = input ().split(",")
words = []
for i in range (len(userinput)):
words.append(userinput)
words.sort()
print (words)
I expect the output should be in alphabetical order but it does not.

Let's say our input is this...
userinput = 'foo,bar'
Using the list comprehension code...
items=[x for x in userinput.split(",")]
items.sort()
print (items)
Output becomes: `['bar', 'foo']`
However, if we use your recreated code..
userinput = userinput.split(',')
words = []
for i in range (len(userinput)):
words.append(userinput)
words.sort()
print (words)
Output becomes: `[['foo', 'bar']]
Why is this?
When the line userinput = userinput.split(',') is run, userinput now becomes ['foo', 'bar'].
Therefore, when words.append(userinput) is run, what it is actually doing is saying words.append(['foo', 'bar']), and thus you are appending a list into a list meaning that words = [['foo', 'bar']].
words.sort() will not sort nested lists within itself, therefore, your list isnt sorted.
Therefore the fix is to append each element of userinput into words instead of appending userinput as a list into words.
userinput = userinput.split(',')
words = []
for i in range (len(userinput)):
words.append(userinput[i])
words.sort()
print (words)
Output becomes: ['bar', 'foo']

Related

How to compare an input() with a variable(list)

(Im using python on Jupiter Notebook 5.7.8)
I have a project in which are 3 lists, and a list(list_of_lists) that refer to those 3.
I want my program to receive an input, compare this input to the content of my "list_of_lists" and if find a match I want to store the match in another variable for later use.
Im just learning, so here is the code I wrote:
first = ["item1", "item2","item3"]
second = ["item4","item5","item6"]
list1 = [first,second]
list2 = ["asd","asd","asd"]
list_of_lists = [list1,list2]
x = input("Which list are you going to use?: ")
for item in list_of_lists:
if item == x:
match = item
print(match)
print('There was a match')
else:
print('didnt match')
I expect a match but it always output "the didnt match",
I assume it fail to compare the contect of the input with the list inside the list_of lists. The question is also why and how to do it properly(if possible), thanks.
input in python3 returns a string. if you want to convert it into a list, use ast.literal_eval or json.loads or your own parsing method.
list_str = input("Which list are you going to use?: ")
user_list = ast.literal_eval(list_str)
assert isinstance(user_list, list)
...
# do your thing...
So here i tried this code, and it does what i desire, I dont know if its too rudimentary and if there is another way to achieve this.
Here I use a second list to catch the moment when there is a match, after I give to that list the value of my true list and from there print it to be used.
I was wondering if there is a way to take out of the ressults the symbols "[]" and the quotes '', so I can have a clean text format, thanks for the help
first = ["item1", "item2","item3"]
second = ["item4","item5","item6"]
list1 = [first,second]
list2 = ["asd","asd","asd"]
list3 = ["qwe","qwe","qwe"]
list_of_lists = [list1,list2,list3]
reference_list = ["list1","list2","list3"]
count = -1
x = input('Which list are you going to use? ')
for item in reference_list:
count += 1
if x == item:
reference_list = list_of_lists
print(reference_list[count])

How can I make my program recognize if item is a string or an intiger?

I'm doing some python challenges for fun and I've found a challenge which tells me to make a program that takes an input and prints the numbers in the message.
but when I run the program it prints nothing but [] in the same number as the letters in the message, and also it do not recognize if a letter is actually a number or not, it just see every letter as a string and prints empty squares.
Here's the code:
WORDS = []
NUMBERS = []
Sentence = input()
for item in Sentence:
if item == str():
WORDS.append(item)
if item == int():
NUMBERS.append(item)
print(('[%s]' % ', '.join(map(str, NUMBERS))))
Have any ideas?
Here is probably what you meant. You have to split the sentence first.
All of the resulting items will be of type string, therefore isinstance will not help.
str.isdigit() checks if a string contains only digits. If it is a number, you can convert it to an integer using int.
WORDS = []
NUMBERS = []
Sentence = input()
for item in Sentence.split():
if item.isdigit():
NUMBERS.append(int(item))
else:
WORDS.append(item)
print(('[%s]' % ', '.join(map(str, NUMBERS))))
If you do not do the split first, it will work too, but give you just single characters in the WORDS list and single numbers in the NUMBERS list.
Typechecking is usually done using isinstance(obj, cls) :
x = 42
print(isinstance(x, int))
print(isinstance(x, str))
but in your case this will not work since input() always returns a string (a string composed of numeric characters is still a string), so the proper solution is to check if the string is composed only of numeric characters (and eventually build an int from it if you need proper ints).
Also, input() returns a single string, and from your namings (WORDS) I assume you want to iterate on the distinct words, not on each characters like you actually do:
words = []
numbers = []
sentence = input()
for item in sentence.strip().split():
if item.isnumeric():
numbers.append(int(item))
else:
words.append(item)
print(('[%s]' % ', '.join(map(str, numbers))))
Use the built-in isinstance function:
if isinstance(item, str):
WORDS.append(item)
if isinstance(item, int):
NUMBERS.append(item)

Return a dictionary with keys that are the first letter of a word and lists of those words?

I want to write a function that takes a list of words and keys and outputs those keys as dictionary keys with any words starting with that letter attached.
How could this be achieved using simple python 3 code?
eg. takes (['apples', 'apple', 'bananna', 'fan'], 'fad')
returns {'a' : ['apple', 'apples'], 'f' : ['fan']}
so far i have tried:
def dictionary(words, char_keys)
char_keys = remove_duplicates(char_keys)
ret = {}
keys_in_dict = []
words = sorted(words)
for word in words:
if word[0] in char_keys and word[0] not in keys_in_dict:
ret[word[0]] = word
keys_in_dict.append(word[0])
elif word[0] in keys_in_dict:
ret[word[0]] += (word)
return ret
This gives kinda the right output but it the output is in a single string rather than a list of strings.(the def is not indented properly i know)
If the input is a list of strings, you can check if the char is in the dict, if yes, append the word, otherwise add a list with the word:
def dictionary(inpt):
result = {}
for word in inpt:
char = word[0]
if char in result:
result[char].append(word)
else:
result[char] = [word]
return result
The modern way to do this is to use a collections.defaultdict with list as argument.
def dictionary(inpt):
result = defaultdict(list)
for word in inpt:
result[word[0]].append(word)
return result
Not sure if your list of inputs are consisted with only strings or it can also include sub-lists of strings (and I'm not so sure why "fad" disappeared in your example). Obviously, in the latter scenario it will need some more effort. For simplicity I assume if contains only strings and here's a piece of code which hopefully points the direction:
d = {}
for elem in input_list[0]:
if elem[0] in input_list[1]
lst = d.get(elem[0], [])
lst.append(elem)
d[elem] = lst

How to iterate over each element in a list?

I have a list of strings and I am iterating over each element by using a for loop, but it seems that what I am doing is iterating over each character instead of each element of the list. For instance:
names = list(input('Enter list of names:')).upper()))
result = []
for i in names:
if 'A' not in i and 'C' in i:
result.append('membership')
elif 'A' in i and 'C' not in i:
result.append('no_membership')
else:
result.append('unknow'):
print(result)
But what I am getting is a list in which the for loop is evaluating each character in the list of strings instead of each name. Am I doing something wrong in the code or do I need to split the elements of the list?
Logically you are just trying to add the entire input into one item of the list
So the first line should read something like:
names = input('Enter list of names:').upper().split()
This will split the inputted string by spaces into a list of separate strings.

Create a dictionary from a file

I am creating a code that allows the user to input a .txt file of their choice. So, for example, if the text read:
"I am you. You ArE I."
I would like my code to create a dictionary that resembles this:
{I: 2, am: 1, you: 2, are: 1}
Having the words in the file appear as the key, and the number of times as the value. Capitalization should be irrelevant, so are = ARE = ArE = arE = etc...
This is my code so far. Any suggestions/help?
>> file = input("\n Please select a file")
>> name = open(file, 'r')
>> dictionary = {}
>> with name:
>> for line in name:
>> (key, val) = line.split()
>> dictionary[int(key)] = val
Take a look at the examples in this answer:
Python : List of dict, if exists increment a dict value, if not append a new dict
You can use collections.Counter() to trivially do what you want, but if for some reason you can't use that, you can use a defaultdict or even a simple loop to build the dictionary you want.
Here is code that solves your problem. This will work in Python 3.1 and newer.
from collections import Counter
import string
def filter_punctuation(s):
return ''.join(ch if ch not in string.punctuation else ' ' for ch in s)
def lower_case_words(f):
for line in f:
line = filter_punctuation(line)
for word in line.split():
yield word.lower()
def count_key(tup):
"""
key function to make a count dictionary sort into descending order
by count, then case-insensitive word order when counts are the same.
tup must be a tuple in the form: (word, count)
"""
word, count = tup
return (-count, word.lower())
dictionary = {}
fname = input("\nPlease enter a file name: ")
with open(fname, "rt") as f:
dictionary = Counter(lower_case_words(f))
print(sorted(dictionary.items(), key=count_key))
From your example I could see that you wanted punctuation stripped away. Since we are going to split the string on white space, I wrote a function that filters punctuation to white space. That way, if you have a string like hello,world this will be split into the words hello and world when we split on white space.
The function lower_case_words() is a generator, and it reads an input file one line at a time and then yields up one word at a time from each line. This neatly puts our input processing into a tidy "black box" and later we can simply call Counter(lower_case_words(f)) and it does the right thing for us.
Of course you don't have to print the dictionary sorted, but I think it looks better this way. I made the sort order put the highest counts first, and where counts are equal, put the words in alphabetical order.
With your suggested input, this is the resulting output:
[('i', 2), ('you', 2), ('am', 1), ('are', 1)]
Because of the sorting it always prints in the above order.

Resources