This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 10 months ago.
I am trying to get my code to go through each element in a list and decipher if it's the letter C. If it's a C remove it and print out the edited list.
Below is my code and it keeps looping.
letters = ["A", "B", "C", "D", "E", "C", "G"]
counter = 0
for letter in letters:
while letter != "":
if letter in letters == "C":
letters.remove("C")
counter += 1
print(letters)
You can do something like this:
With the pop argument
letters = ["A", "B", "C", "D", "E", "C", "G"]
counter = 0
i=0
while i < len(letters):
if i<len(letters) and letters[i] == "C":
letters.pop(i)
counter += 1
else:
i+= 1
print(letters) #['A', 'B', 'D', 'E', 'G']
You can remove the counter and obtain the number of "C" in the list by doing:
letters.count("C") at the begging
And you can use that to do:
With remove
letters = ["A", "B", "C", "D", "E", "C", "G"]
for _ in range(letters.count('C')):
letters.remove('C')
print(letters) #['A', 'B', 'D', 'E', 'G']
You can also use a list comprehension like that:
With list comprehension
letters = ["A", "B", "C", "D", "E", "C", "G"]
letters = [l for l in letters if l != 'C']
print(letters) #['A', 'B', 'D', 'E', 'G']
Or, you could also use filter with a lambda function:
With filter
letters = ["A", "B", "C", "D", "E", "C", "G"]
letters = [*filter(lambda l: l!='C', letters)]
print(letters) #['A', 'B', 'D', 'E', 'G']
Related
How would you code a program ( preferably in Java or Python ) to break a random ciphertext where key can't be determined by shifts i.e the key substitution is random.
This website (https://www.guballa.de/substitution-solver) has done it.
I have to do it by frequency analysis (https://en.wikipedia.org/wiki/Frequency_analysis)
The main problem I am facing is to check that if the words are looking like English words or not when I substitute.
Please guide me on how to approach this problem
Thanks
hakid
This is maybe a late answer but this code can used as a start for you.
from operator import itemgetter
letterFrequency = [
[12.00, 'E'], [9.10, 'T'],
[8.12, 'A'], [7.68, 'O'],
[7.31, 'I'], [6.95, 'N'],
[6.28, 'S'], [6.02, 'R'],
[5.92, 'H'], [4.32, 'D'],
[3.98, 'L'], [2.88, 'U'],
[2.71, 'C'], [2.61, 'M'],
[2.30, 'F'], [2.11, 'Y'],
[2.09, 'W'], [2.03, 'G'],
[1.82, 'P'], [1.49, 'B'],
[1.11, 'V'], [0.69, 'K'],
[0.17, 'X'], [0.11, 'Q'],
[0.10, 'J'], [0.07, 'Z']]
plain_to_cipher = {
"a": "l", "b": "f",
"c": "w", "d": "o",
"e": "a", "f": "y",
"g": "u", "h": "i",
"i": "s", "j": "v",
"k": "z", "l": "m",
"m": "n", "n": "x",
"o": "p", "p": "b",
"q": "d", "r": "c",
"s": "r", "t": "j",
"u": "t", "v": "q",
"w": "e", "x": "g",
"y": "h", "z": "k",
}
cipher_to_plain = {v: k for k, v in plain_to_cipher.items()}
alphabet = "qwertyuioplkjhgfdsazxcvbnm"
message = input("Enter message to encrypt: ")
message = message.lower()
ciphertext = ""
for c in message:
if c not in alphabet:
ciphertext += c
else:
ciphertext += plain_to_cipher[c]
print("\nRandom substitution Encryption is: \n\t{}".format(ciphertext))
# .......................................................................
# calculate letter frequency of ciphertext
letter_list = []
cipher_len = 0
for c in ciphertext:
if c in alphabet:
cipher_len += 1
if c not in letter_list:
letter_list.append(c)
letter_freq = []
for c in letter_list:
letter_freq.append([round(ciphertext.count(c) / cipher_len * 100, 2), c])
# ....................................................................................
# Now sort list and decrypt each instance of ciphertext according to letter frequency
letter_freq = sorted(letter_freq, key=itemgetter(0), reverse=True)
decrypted_plaintext = ciphertext
index = 0
for f, c in letter_freq:
print("Replacing {} of freq {} with {}.".format(c, f, letterFrequency[index][1]))
decrypted_plaintext = decrypted_plaintext.replace(c, letterFrequency[index][1])
index += 1
print("\nThe Plaintext after decryption using frequency analysis: \n\t{}".format(decrypted_plaintext))
SIDE NOTES: this program can most of the time successfully decrypt most used letters like e, t, a, o but would fail to successfully map less used letters(since frequency differences start to decrease making results less predictable). This problem can be overcomed a little bit by also analyzing English most used bigrams(like th) and using the results to make more accurate predictions. Another note you can take advantage of is that the letter a is easy to break making breaking the letter i less painfull since any sentence having one ciphertext character in between is likely to correspond to a(ex: a book) or i(ex: i went)(and we already deduced a so any other single ciphertext character is likely to be i)
I have a multidimensional list that I would like to return 2 or more duplicates but I don't know what code to use.
For example here is my list
A=[[a,b],[b,c],[g,i],[a,c],[a,b],[a,b],[b,c]]
I would like to return 2 or more duplicates in my list. So it would be something like this
b=[[a,b],[b,c]]
You can use a Counter, converting the lists into tuples so they can be hashed (and then counted), and then filtering the counter based on the count being 2 or more:
from collections import Counter
A = [["a", "b"], ["b", "c"], ["g", "i"], ["a", "c"], ["a", "b"], ["a", "b"],["b", "c"]]
counts = Counter(map(tuple, A))
b = [list(t) for t, c in counts.items() if c > 1]
print(b)
Output:
[['a', 'b'], ['b', 'c']]
You can use Python's built-in function count() to determine occurrences of an item in a list. To achieve what you're looking for, you can do something like the following:
a = [["a", "b"], ["b", "c"], ["g", "i"], ["a", "c"], ["a", "b"], ["a", "b"],["b", "c"]]
dupes = list()
for item in a:
if a.count(item) > 1 and item not in dupes:
dupes.append(item)
print(dupes)
>>> [['a', 'b'], ['b', 'c']]
Im trying to do this: if an element of list1 is in list2, that element would have to be replaced with a random element.
It would some something like this:
replace(["a","b","c"],"x",["c","n","a","b","l"])
And i would have to return this:
["x","n","x","x","l"]
You can use list-comprehension for that.
For example:
def replace(lst1, elem, lst2):
s = set(lst1)
return [elem if v in s else v for v in lst2]
out = replace(["a", "b", "c"], "x", ["c", "n", "a", "b", "l"])
print(out)
Prints:
['x', 'n', 'x', 'x', 'l']
I have a dictionary object,
z = {"a":3, "b":2, "c":5}
Based on that,
I desire to get output object as pandas series or array as,
array(["a", "a", "a", "b", "b", "c", "c", "c", "c", "c"])
Even if elements in output series are not in order that is fine, but should reflect same count as of value for its respective key element in input dictionary.
use np.repeat
import numpy as np
np.repeat(*zip(*z.items()))
#array(['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'c'], dtype='<U1')
here is one solution :
z = {"a":3, "b":2, "c":5}
list=[]
for i in z: list += [i]*z[i]
print(list)
['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'c']
I want to sort a list of strings alphabetically and by length so it gets sorted like this:
["a", "b", "ba", "ab", "cccc", "cccef", "c"]
to
["a", "ab", "b", "ba", "c", "cccc", "cccef"]
It's probably a duplicate question and the solution is probably quite simple but i can't seem to figure it out.
The first argument is just x which sorting by alphabetically(default) and the second is len(x) which sort by the length.
s = ["a", "b", "ba", "ab", "cccc", "cccef", "c"]
s = sorted(s, key = lambda x: (x,len(x)))
print (s)
>>>['a', 'ab', 'b', 'ba', 'c', 'cccc', 'cccef']