Python: increment index range by 1 - python

I have this code:
f = open('story.txt', 'r')
story = f.read()
a = 0
b = 2
active_words = story[a:b]
I'm trying to make it so later on in the program I can increase the range of this index by (+1), so that instead of taking one word out of the story as active_words, it takes 2,3,4... etc. Ideally this would be able to happen inside part of a while loop.
My apologies for my lack of formatting, this is my first post.
I'm also just starting to learn python and so there's probably a dead easy solution I've overlooked... I've tried trying to define a function like extend(active_words), but to no avail.
Thanks in advance!

A basic nested for-loop seems to be what you are looking for:
n = len(story)
for k in range(2,n+1):
for j in range(n-k+1):
active_words = story[j:j+k]
The outer loop controls the length of the slice and the inner loop actually generates the slices.
Note that these are just string slices, which will contain fragments of words. You might want something like story = story.split() prior to the loop.

Are you trying to split a sentence into words?
if so, try instead using:
story = f.read()
words = story.split()
for word in words:
print(word)

Related

How to append only unique values to a key in a dictionary?

sorry this is likely a complete noob question, although I'm new to python and am unable to implement any online suggestions such that they actually work. I need decrease the run-time of the code for larger files, so need to reduce the number of iterations i'm doing.
How do I modify the append_value function below to append only UNIQUE values to dict_obj, and remove the need for another series of iterations to do this later on.
EDIT: Sorry, here is an example input/output
Sample Input:
6
5 6
0 1
1 4
5 4
1 2
4 0
Sample Output:
1
4
I'm attempting to solve to solve:
http://orac.amt.edu.au/cgi-bin/train/problem.pl?problemid=416
Output Result
input_file = open("listin.txt", "r")
output_file = open("listout.txt", "w")
ls = []
n = int(input_file.readline())
for i in range(n):
a, b = input_file.readline().split()
ls.append(int(a))
ls.append(int(b))
def append_value(dict_obj, key, value): # How to append only UNIQUE values to
if key in dict_obj: # dict_obj?
if not isinstance(dict_obj[key], list):
dict_obj[key] = [dict_obj[key]]
dict_obj[key].append(value)
else:
dict_obj[key] = value
mx = []
ls.sort()
Dict = {}
for i in range(len(ls)):
c = ls.count(ls[i])
append_value(Dict, int(c), ls[i])
mx.append(c)
x = max(mx)
lss = []
list_set = set(Dict[x]) #To remove the need for this
unique_list = (list(list_set))
for x in unique_list:
lss.append(x)
lsss = sorted(lss)
for i in lsss:
output_file.write(str(i) + "\n")
output_file.close()
input_file.close()
Thank you
The answer to your question, 'how to only append unique values to this container' is fairly simple: change it from a list to a set (as #ShadowRanger suggested in the comments). This isn't really a question about dictionaries, though; you're not appending values to 'dict_obj', only to a list stored in the dictionary.
Since the source you linked to shows this is a training problem for people newer to coding, you should know that changing the lists to sets might be a good idea, but it's not the cause of the performance issues.
The problem boils down to: given a file containing a list of integers, print the most common integer(s). Your current code iterates over the list, and for each index i, iterates over the entire list to count matches with ls[i] (this is the line c = ls.count(ls[i])).
Some operations are more expensive than others: calling count() is one of the more expensive operations on a Python list. It reads through the entire list every time it's called. This is an O(n) function, which is inside a length n loop, taking O(n^2) time. All of the set() filtering for non-unique elements takes O(n) time total (and is even quite fast in practice). Identifying linear-time functions hidden in loops like this is a frequent theme in optimization, but profiling your code would have identified this.
In general, you'll want to use something like the Counter class in Python's standard library for frequency counting. That kind of defeats the whole point of this training problem, though, which is to encourage you to improve on the brute-force algorithm for finding the most frequent element(s) in a list. One possible way to solve this problem is to read the description of Counter, and try to mimic its behavior yourself with a plain Python dictionary.
Answering the question you haven't asked: Your whole approach is overkill.
You don't need to worry about uniqueness; the question prompt guarantees that if you see 2 5, you'll never see 5 2, nor a repeat of 2 5
You don't even care who is friends with who, you just care how many friends an individual has
So don't even bother making the pairs. Just count how many times each player ID appears at all. If you see 2 5, that means 2 has one more friend, and 5 has one more friend, it doesn't matter who they are friends with.
The entire problem can simplify down to a simple exercise in separating the player IDs and counting them all up (because each appearance means one more unique friend), then keeping only the ones with the highest counts.
A fairly idiomatic solution (reading from stdin and writing to stdout; tweaking it to open files is left as an exercise) would be something like:
import sys
from collections import Counter
from itertools import chain, islice
def main():
numlines = int(next(sys.stdin))
friend_pairs = map(str.split, islice(sys.stdin, numlines)) # Convert lines to friendship pairs
counts = Counter(chain.from_iterable(friend_pairs)) # Flatten to friend mentions and count mentions to get friend count
max_count = max(counts.values()) # Identify maximum friend count
winners = [pid for pid, cnt in counts.items() if cnt == max_count]
winners.sort(key=int) # Sort winners numerically
print(*winners, sep="\n")
if __name__ == '__main__':
main()
Try it online!
Technically, it doesn't even require the use of islice nor storing to numlines (the line count at the beginning might be useful to low level languages to preallocate an array for results, but for Python, you can just read line by line until you run out), so the first two lines of main could simplify to:
next(sys.stdin)
friend_pairs = map(str.split, sys.stdin)
But either way, you don't need to uniquify friendships, nor preserve any knowledge of who is friends with whom to figure out who has the most friends, so save yourself some trouble and skip the unnecessary work.
If you intention is to have a list in each value of the dictionary why not iterate the same way you iterated on each key.
if key in dict_obj.keys():
for elem in dict_obje[key]: # dict_obje[key] asusming the value is a list
if (elem == value):
else:
# append the value to the desired list
else:
dic_obj[key] = value

Appending list using .capitalize() - compiler freezes with high RAM usage

I'm trying to swap str elements in list with same elements but capitalize their first letter.
While trying to achieve this I'm just step by stepping it and when I try to use for loop to just append list with capitalized elements, my compiler freezes and proceeds to gradually increase in RAM usage up to 90%.
I can guess it has to do something with built in functions that I use (probably incorrectly). Can anyone help me understand what is happening and how should I approach it?
Here is code:
title = 'a clash of KINGS'
out = title.split()
for i in out:
out.append(i.capitalize())
Don't change a list while iterating over it. You keep adding elements to out list. You can print out inside the loop and see for yourself. Even if it didn't enter into infinite loop, still you did not replace the initial values, but just add more and more elements.
you can use list comprehension
title = 'a clash of KINGS'
out = title.split()
out = [word.capitalize() for word in out]
you can combine last 2 lines into one
title = 'a clash of KINGS'
out = [word.capitalize() for word in title.split()]
I think you are in a infinite loop. You're not accessing the out element, you're keep appending a lot of elements inside the list. I think what you're trying to do is:
title = 'a clash of KINGS'
out = title.split()
for i in range(len(out)):
out[i] = out[i].capitalize()

Converting list (array values) into integers and then print out the input which the array holds as the converted integers not words

firstsentence = input('Enter a sentence: ')
firstsentence = firstsentence.lower()
words = firstsentence.split(' ')
my_list = []
my_list.append(words)
for (i, firstsentence) in enumerate(my_list):
if (aword == my_list): #This is where i get confused
print(str(i+1)+ ' position')
print (my_list)
So what i am try to do is ask the user for an input - "firstsentence". I will then try to split the inputted sentence into words and store them in the array (list) my_list. I am getting stuck on how to convert the seperated words into numbers (their positions in the sentence) and then printing out the input("firstsentence") as the integer version. 'aword' is what i used to try and identify if the word was repeated in the sentence. This is quite confusing and here is an example :-
"I like to do coding because I like it and i like it a lot"
There are 15 words here. Of these 15, only 10 are different. So the repeated words MUST be put into the same integer (even though their positions are different their actual word is the same) value in the array. The code i want to print out should look like this for the sentence above:-
1 2 3 4 5 6 1 2 7 8 1 2 7 9 10. I am really confused as to how to store the separated words as different values (integers) and then especially on how to store the same repeating words as one value, and then printing the whole thing out. Thanks to those who help. Would be much appreciated :-).
My answer is deliberately incomplete. It's clear you're new at this, and part of being new is discovering how code works. But you're lacking in some basic concepts of what to do with lists in python, and this should point you in the right direction.
firstsentence = input('Enter a sentence: ')
firstsentence = firstsentence.lower()
words = firstsentence.split(' ')
my_list = []
for word in words:
print(word in my_list)
# You can do something more useful than print here, right?
# Maybe add the specific word to my_list...
for word in words:
print(my_list.index(word))
# This gives you the index, but you need to figure out how to output it the way you want
# Note that indices in python start at 0 while your sample output starts
# at 1. So maybe do some addition somewhere in here.
So, what's happening here?
We're doing two passes.
Generally, you'll get very far in programming if you can decompose a problem into discrete steps. In this case, there are two steps to your problem - find the index of the first occurrence of each word, and then output the right indices.
In the first pass, you'll create a list of unique words, where their ordering reflects their ordering in the sentence.
In the second pass, you'll go through the original sentence and look up the place where it first occurred, and format that the way you need.
If you're really attentive, you'll realize: you could easily do this in one pass. What does the second pass require? Just that the word you're looking for be in my_list. As long as you meet that requirement, you could combine the two loops. This is a good thing to do - it may not matter when you're looking at 20 words, but what if you were looking at 20,000,000,000 words? You'd really only want one loop. But take small steps. Start by figuring out how to do it with two loops, and then maybe move on to putting it all in one.

For Loop questions

I'm used to seeing For Loops in this format:
for number in l:
sum = sum + number
I was browsing some forums and came across this piece of code:
count_chars = ".arPZ"
string = "Phillip S. is doing a really good job."
counts = tuple(string.count(d) for(d) in count_chars)
print counts
I'm not sure if that is really a For loop, so I decided to rewrite it in a way that I understood:
tuple(
for(d) in count_chars:
string.count(d))
Needless to say, it failed lol. So can someone explain what is going on, and explain the folly of my logic? Thanks!!
It's not quite a for loop as such, but a generator expression. What it basically does is return an iterator where each element is the amount of time every character in count_chars occurs in d. It then adds all of these elements into a tuple.
It is (roughly) equivalent to:
counts = []
for d in count_chars:
counts.append(string.count(d))
counts = tuple(counts)

Printing one character at a time from a string, using the while loop

Im reading "Core Python Programming 2nd Edition", They ask me to print a string, one character at a time using a "while" loop.
I know how the while loop works, but for some reason i can not come up with an idea how to do this. I've been looking around, and only see examples using for loops.
So what i have to do:
user gives input:
text = raw_input("Give some input: ")
I know how to read out each piece of data from an array, but i can't remember anything how to do it to a string.
Now all i need is working while-loop, that prints every character of the string, one at a time.
i guess i've to use len(text), but i'm not 100% sure how to use it in this problem.
Some help would be awsome! I'm sure this is a very simple issue, but for some reason i cannot come up with it!
Thx in advance! :)
I'm quite sure, that the internet is full of python while-loops, but one example:
i=0
while i < len(text):
print text[i]
i += 1
Strings can have for loops to:
for a in string:
print a
Other answers have already given you the code you need to iterate though a string using a while loop (or a for loop) but I thought it might be useful to explain the difference between the two types of loops.
while loops repeat some code until a certain condition is met. For example:
import random
sum = 0
while sum < 100:
sum += random.randint(0,100) #add a random number between 0 and 100 to the sum
print sum
This code will keep adding random numbers between 0 and 100 until the total is greater or equal to 100. The important point is that this loop could run exactly once (if the first random number is 100) or it could run forever (if it keeps selecting 0 as the random number). We can't predict how many times the loop will run until after it completes.
for loops are basically just while loops but we use them when we want a loop to run a preset number of times. Java for loops usually use some sort of a counter variable (below I use i), and generally makes the similarity between while and for loops much more explicit.
for (int i=0; i < 10; i++) { //starting from 0, until i is 10, adding 1 each iteration
System.out.println(i);
}
This loop will run exactly 10 times. This is just a nicer way to write this:
int i = 0;
while (i < 10) { //until i is 10
System.out.println(i);
i++; //add one to i
}
The most common usage for a for loop is to iterate though a list (or a string), which Python makes very easy:
for item in myList:
print item
or
for character in myString:
print character
However, you didn't want to use a for loop. In that case, you'll need to look at each character using its index. Like this:
print myString[0] #print the first character
print myString[len(myString) - 1] # print the last character.
Knowing that you can make a for loop using only a while loop and a counter and knowing that you can access individual characters by index, it should now be easy to access each character one at a time using a while loop.
HOWEVER in general you'd use a for loop in this situation because it's easier to read.
Try this procedure:
def procedure(input):
a=0
print input[a]
ecs = input[a] #ecs stands for each character separately
while ecs != input:
a = a + 1
print input[a]
In order to use it you have to know how to use procedures and although it works, it has an error in the end so you have to work that out too.
Python allows you to use a string as an iterator:
for character in 'string':
print(character)
I'm guessing it's your job to figure out how to turn that into a while loop.
# make a list out of text - ['h','e','l','l','o']
text = list('hello')
while text:
print text.pop()
:)
In python empty object are evaluated as false.
The .pop() removes and returns the last item on a list. And that's why it prints on reverse !
But can be fixed by using:
text.pop( 0 )
Python Code:
for s in myStr:
print s
OR
for i in xrange(len(myStr)):
print myStr[i]
Try this instead ...
Printing each character using while loop
i=0
x="abc"
while i<len(x) :
print(x[i],end=" ")
print(i)
i+=1
This will print each character in text
text = raw_input("Give some input: ")
for i in range(0,len(text)):
print(text[i])

Categories

Resources