How to sub-string a list in Python - python

I have an assignment where I have a list with two names and I have to print the first name and then I have to print the last name.
names_list = ['Oluwaferanmi Fakolujo', 'Ajibola Fakolujo']
I have two names and then when I find the whitespace between them I have to print both the first name and the last name out of the list and put it into a variable.
I have tried to slice it but I don't understand it enough to use it. Here is an example:
substr = x[0:2]
This just brings both names instead of only substring it.

names_list = ['Oluwaferanmi Fakolujo', 'Ajibola Fakolujo']
for i in range(0, len(names_list)):
nf = names_list[i].split(' ')
name = nf[0]
family = nf[1]
print("Name is: {}, Family is: {}".format(name, family))
Output:
Name is: Oluwaferanmi, Family is: Fakolujo
Name is: Ajibola, Family is: Fakolujo

This will only work for Python 3.x
You can use the split() method and indexing for these kinds of problems.
Iterate through the list
split() the string
Store the values in a variable, so that we can index them
Display the values
names_list = ['Oluwaferanmi Fakolujo', 'Ajibola Fakolujo']
for i in names_list:
string = i.split(" ")
first_name = string[0]
last_name = string[1]
print(f"First Name: {first_name} Last Name: {last_name}")

Related

How to use sep parameter in .format?

I just started learning python and I'm experimenting new things.
isim = input("Name:")
soyad = input("Surname:")
yaş = input("Age:")
edu = input("Education:")
gen = input("Gender:")
print("Name: {},Surname: {},Age: {},Education: {},Gender: {}".format(
isim,soyad,yaş,edu,gen))
My aim is to use \n after all brackets ({}) so I'll be able to print them more organised but I don't want to use \n after every part.
print(a,b,c,d,e,sep = \n)
is the only way I know. I want to use sep and format together. How can I do that?
You're only printing one string created by using format so sep doesn't apply. You could expand a generator expression that adds "\n" to each argument to format, though.
print("Name: {},Surname: {},Age: {},Education: {},Gender: {}".format(
*(f"{x}\n" for x in [isim,soyad,yaş,edu,gen])))
You may instead wish to use a multi-line f-string, though.
print(f"""Name: {isim}
Surname: {soyad}
Age: {yaş}
Education: {edu}
Gender: {gen}""")
Personally, I'd just format your print statement like:
print(f"Name: {isim}",f"Surname: {soyad}",f"Age: {yaş}",f"Education: {edu}",f"Gender: {gen}", sep='\n')
# OR
print(f"Name: {isim}\nSurname: {soyad}\nAge: {yaş}\nEducation: {edu}\nGender: {gen}")
As an alternative to #Chris's comprehensive answer, you can simply apply replace before formatting your string:
print("Name: {},Surname: {},Age: {},Education: {},Gender: {}".replace('{}', '{}\n').format(isim,soyad,yaş,edu,gen))
A systematical approach which depends entirely on the type of field entries. Data stored into dictionary, then a single string is constructed using format and join.
# fields names
fields = ("Name",
"Surname",
"Age",
"Education",
"Gender")
# used a dictionary to store the input results
data = {field: input(field) for field in fields}
# key-value template
template_string = '{}: {{}}'
# add the keys
field_names = map(template_string.format, data)
# add the values (with separator ",\n")
result = ',\n'.join(field_names).format(*data.values())
# check result
print(result)
Another similar way could be to use the "var=" property of f-strings. Requirement: the variables identifiers should be chosen properly since they will part of the final string. Side-effect: there are = around... if no conflicts they can be substituted with
Name = input("Name:")
Surname = input("Surname:")
Age = input("Age:")
Education = input("Education:")
Gender = input("Gender:")
# var= property of f-string
result = f'{Name=}\n{Surname=}\n{Age=}\n{Education=}\n{Gender=}'
# if no conflicts with = symbol
result = result.replace('=', ': ')
print(result)
How to use format and sep together? Taking as reference the approach in the question: a list is required, if no conflicts with other characters, split it at ,:
# ...
result = "Name: {},Surname: {},Age: {},Education: {},Gender: {}".format(isim,soyad,yaş,edu,gen)
print(*result.split(','), sep='\n')

Function that finds duplicate names by inputting a name list

guys I'm a beginner who is new to Python.
I want to create mthod which find duplicate name in list. So, I created it but it doesn't work the way I want.
This is my code
def find_same_name(name) :
result = set()
for i in range(0 , len(name) - 1) :
for j in range(i + 1, len(name)) :
if name[i] == name[j] :
result.add(name[i])
return result
name = input("Please Write Name ")
print(name)
#print(type(name))
print(find_same_name(name))
And this is my result
Please Write Name Tom Jerry Mike Tom Kim
Tom Jerry Mike Tom Kim
{'T', 'o', ' ', 'e', 'r', 'i', 'm'}
Why it print as type character? I don't know what is wrong. Would you guys pleas help me?
The reason is that you are iterating over each letter in the list, not every name. To iterate over every name you can use the .split() function which splits a string into a list based on (by default) the spaces.
def find_same_name(name) :
allnames = name.split()
result = set()
for i in range(0 , len(allnames) - 1) :
for j in range(i + 1, len(name)) :
if allnames[i] == allnames[j] :
result.add(name[i])
return result
name = input("Please Write Names: ")
print(name)
print(find_same_name(name))
name = input("Please Write Name ").split(' ')
It is a simple mistake you made.
You are using the name as a string instead of list of names. Use 'split' to make the given names into list and apply the function
name = input("Please Write Name ")
This line assign name as a string. So when you do name[i] in the function, it returns a single letter.
To solve that, assign name as a list:
name = input("Please Write Name ").split()
The split() method transforms the string with seperate names into a list that records all seperate name, so you can use name[i] to get the names.
Hello and welcome to stackoverflow.
your problem is, that you want to hand over a list of names to your method, but your are currently hand over a single string "Tom Jerry Mike Tom Kim Tom Jerry Mike Tom Kim". If you do this, python will access the single letters withing the string and not the words. I guess, you want to split the input on spaces, which can be done by:
name = input("Please Write Name ")
name_list = name.split(" ")
print(name_list)
print(type(name)) # will be list now, not str
print(find_same_name(name_list))

Remove unwanted substring from a list of strings at specified indexes

New to python and I want to remove the prefix of two stings. Just leaving everything before the J and removing the .json.
I tried using [:1] but it removes the entire first string
name = ['190523-105238-J105150.json',
'190152-105568-J616293.json']
I want to output this
name = ['J105150',
'J616293']
You can use split() in a list-comprehension:
name = ['190523-105238-J105150.json',
'190152-105568-J616293.json']
print([x.rsplit('-', 1)[1].split('.')[0] for x in name])
# ['J105150', 'J616293']
You could use find() function and array splicing.
name = ['190523-105238-J105150.json' ,'190152-105568-J616293.json']
for i in range(len(name)):
start_of_json = name[i].find('.json')
start_of_name = name[i].find('J')
name[i] = name[i][start_of_name:start_of_json]
Doing [:1] will slice your current list to take only elements that are before index 1, so only element at index 0 will be present.
This is not what you want.
A regex can help you reach your goal.
import re
output = [re.search(r'-([\w+]).json', x).group(0) for x in your_list]
Firstly it is not a data frame, it is an array.
You could use something simple as below line for this, assuming you have static structure.
name = [x[x.index("J"):x.index(".")] for x in name]
Here are two possible approaches:
One is more verbose. The other does essentially the same thing but condenses it into a one-liner, if you will.
Approach 1:
In approach 1, we create an empty list to store the results temporarily.
From there we parse each item of name and .split() each item on the hyphens.
For each item, this will yield a list composed of three elements: ['190523', '105238', 'J105150.json'] for example.
We use the index [-1] to select just the last element and then .replace() the text .json with the empty string '' effectively removing the .json.
We then append the item to the new_names list.
Lastly, we overwrite the variable label name, so that it points at the new list we generated.
name = ['190523-105238-J105150.json', '190152-105568-J616293.json']
new_names = []
for item in name:
item = item.split('-')[-1]
new_names.append(item.replace('.json', ''))
name = new_names
Approach 2:
name = ['190523-105238-J105150.json', '190152-105568-J616293.json']
name = [item.split('-')[-1].replace('.json', '') for item in name]
Originally the list is name = ['190523-105238-J105150.json', '190152-105568-J616293.json'].
List comprehensions in python are extremely useful and powerful.
eq = [name[i][name[i].find("J"):name[i].rfind(".json")] for i in range(len(name))], a list comprehension is used to create a new list of values from the list name by finding the starting at the value J and going to before the .json. The result of find() is of type integer.
The complete code can be seen below.
def main():
name = ['190523-105238-J105150.json', '190152-105568-J616293.json']
eq = [name[i][name[i].find("J"):name[i].rfind(".json")] for i in range(len(name))]
print(eq)
if __name__ == "__main__":
main()
output: ['J105150', 'J616293']

Integrating Wildcard In Comparison of Strings

I have a python script which takes a name, re-formats it, and then compares it to a list of other names to see how many times it matches. The issue is the names it is being compared to have middle initials (which I don't want to have entered in the script).
list_of_names = ['Doe JM', 'Cruz CR', 'Smith JR', 'Doe JM', 'Maltese FL', 'Doe J']
Now I have a simple function that reformats the name.
f_name = name_format('John','Doe')
print(f_name)
> 'Doe J'
Now I want to do comparisons where everytime "Doe J" or "Doe JM" appears, the value is true. The below function would not work as intended.
def matches(name, list):
count = 0
for i in list:
if i == name:
count = count + 1
else:
pass
return(count)
print (matches(f_name, list_of_names))
> 1
My goal is to make the return equal to 3. To do these, I want ignore the middle initial which in this case would be 'M' in 'Doe JM'.
What I want to do is something along the lines of formatting the name to 'Doe J?' where '?' is a wild card. I tried importing fnmatch and re to use some of their tools but was unsuccessful.
Use two for and yield. Function will return duplicate values and you need use set for remove it:
list_of_names = ['Doe JM', 'Cruz CR', 'Smith JR', 'Doe JM', 'Maltese FL', 'Doe J']
# List of names
def check_names(part_names, full_name_list):
for full_name in full_name_list:
for part_name in part_names:
if part_name in full_name:
yield full_name
result = set(check_names(['Doe J', 'Cruz'], list_of_names))
# One name
def check_names(name, full_name_list):
for full_name in full_name_list:
if name in full_name:
yield full_name
result = check_names('Doe J', list_of_names)
print list(result) # List of result
print len(result) # Count of names
You were on the right track with the re module. I believe the solution to your problem would be:
import re
def matches(name, name_list):
regex = name + '\w?' # Allows one addition word character after the name
result = list(map(lambda test_name: re.match(regex, test_name) is not None, name_list))
return result.count(True)
print(matches(f_name, list_of_names))
# 3
This solution ensures that exactly one alphanumeric character is allowed after the name.

Loop to find decrementing whole word string in a list

I have a string variable that is a person's first and middle names, which have been accidentally concatenated. Let's call it firstMiddle="johnadam"
I need to identify what's the first name and what isn't, and then split them into different variables. So I have this big text file full of first names, and the idea is that you check the full firstMiddle string to see if it's in the list, and if it isn't, then you decrement by one character and retry. (if you increment you fail, e.g. "max" from "maxinea")
I have tried writing this a hundred different ways, and my problem seems to be that I can't get it to x in y a whole word (this \b regex stuff only works on actual strings and not string variables?). The best outcome I had decremented "johnadam" down to "johna" because there is a name "johnathan" in the list. Now I can't even remember how I did that and my current code decrements just once and then quits even though nameToMatch in nameList == False.
I'm a total noob. I know I'm doing something very obviously stupid. Please help. Here's some code:
firstMiddle = "johnadam"
nameToCheck = firstMiddle
for match in nameList:
if nameToCheck not in nameList:
nameToCheck = nameToCheck[:-1]
break
firstName = nameToCheck
middleName = firstMiddle.partition(nameToCheck)[2]
firstMiddle = "johnadam"
nameToCheck = firstMiddle
nameList = ['johnathan', 'john', 'kate', 'sam']
while nameToCheck not in nameList:
nameToCheck = nameToCheck[:-1]
firstname = nameToCheck
middleName = firstMiddle[ len(firstName): ]
This is a simple change from what Gabriel has done. The concept is basically the same. This one just looks at the longest match rather than the first match. Its difficult to put the entire code in the comment section so answering separately.
firstMiddle = "johnadam"
nameToCheck = firstMiddle
nameList = ['johnathan', 'john', 'kate', 'sam']
firstNames = filter(lambda m: firstMiddle.startswith(m), nameList)
middleName = ''
if firstNames: # if the list isnt empty
firstName = sorted( firstNames, key=len )[-1]
middleName = firstMiddle.partition(firstName)[2]
else:
firstName = firstMiddle
print firstName
See if this works ...
You could do this in a brute force way.
Iterate over the mixedname and slice it every time a bit more.
So you get
['johnadam']
['johnada','m']
['johnad','am']
['johna','dam']
['john','adam'] # your names in the list
If one of them match you put them aside and keep doing it until all of them are match.
If you have names that start same like 'john' and 'johnathan' or are in middle of other names, like 'natham' and 'johnathan' you should not stop when you find a match, but keep doing the slicing, so you get ['john','athan'] and ['joh','nathan']
mixnames = ['johnadam','johnathan','johnamax']
names = ['john','adam', 'johnathan','nathan','max']
foundnames = []
for name in mixnames:
for i in xrange(len(name)):
name1 = name[0:i+1]
name2 = name[i:]
if name1 in names and name1 not in foundnames:
foundnames.append(name1)
if name2 in names and name2 not in foundnames:
foundnames.append(name2)
print foundnames
output:
['john', 'adam', 'johnathan', 'nathan', 'max']

Categories