61

I'm relatively new to Python and it's libraries and I was wondering how I might create a string array with a preset size. It's easy in java but I was wondering how I might do this in python.

So far all I can think of is

strs = ['']*size

And some how when I try to call string methods on it, the debugger gives me an error X operation does not exist in object tuple.

And if it was in java this is what I would want to do.

String[] ar = new String[size];
Arrays.fill(ar,"");

Please help.

Error code

    strs[sum-1] = strs[sum-1].strip('\(\)')
AttributeError: 'tuple' object has no attribute 'strip'

Question: How might I do what I can normally do in Java in Python while still keeping the code clean.

if_zero_equals_one
  • 1,716
  • 4
  • 17
  • 30
  • I don't get an error when I try your code using `ar`. What is the declaration of `strs`? – GWW Jun 16 '11 at 18:42
  • 1
    Why are you trying to create an array of empty strings? Python usually has better ways to deal with string arrays. – yan Jun 16 '11 at 18:43
  • sorry about that ar was strs and it's for a list of things more or less a map with less syntax – if_zero_equals_one Jun 16 '11 at 18:45
  • 8
    For your basic issue, read this: http://dirtsimple.org/2004/12/python-is-not-java.html – Gerrat Jun 16 '11 at 18:46
  • Clearly you are going to populate this "array" with real data, why not start with a blank list and just .append() the real data as needed? – kurosch Jun 16 '11 at 18:47
  • I got that issue solved now the "advanced" issue. I know I've already noticed my codes from java are shrinking and that Python is much slower at running things. – if_zero_equals_one Jun 16 '11 at 18:49
  • What *actual* problem are you trying to solve here? This pattern makes no sense. – Daenyth Jun 16 '11 at 18:49
  • 1
    because it doesn't come in a 1, 2, 3, ... order it goes more like 1, 99, 32, 176, 903, 4, 67...and an access on an array is O(1) v. O(n) on a list search for things that are smaller. – if_zero_equals_one Jun 16 '11 at 18:50
  • 2
    Python is not *slower* at running things. You are just not good at programming it. – JBernardo Jun 16 '11 at 18:53
  • Running translated code straight from java. The execution time was nowhere near equivalent of that of java. – if_zero_equals_one Jun 16 '11 at 18:56
  • 2
    Exactly. Bad java habits are bad – JBernardo Jun 16 '11 at 19:01
  • It's the exact same code dealing with loop, modulus, and concatenation of strings. BASIC code. It should be able to execute it easily enough. – if_zero_equals_one Jun 16 '11 at 19:02
  • 6
    Accidentally right. Running similar code in Python has a much higher overhead (regardless of implementation, only the exact difference changes), but that's not because some code you barely got running on Python doesn't run as fast as a decent Java program. Show your code and I'll propably find five things one can optimize about it while actually making it more idiomatic and readable. And to cite an old metaphor: would you rather spend five hours getting a program in a static language to work and watch it complete in a second or have a coffee while the 10 minutes script takes its 10 seconds? ;) –  Jun 16 '11 at 19:05
  • Sorry it's a different code than that which is being discussed on this page. I don't worry it's just I need to learn what, why, and how for Python for the future. I'm asking the why against speed and how on the arrays. I do have to say Python does exceed expectations on it's main goal of readability though. And it still took like 3 minutes vs the java programs 5 seconds which actually took less time to write because of familiarity lol. – if_zero_equals_one Jun 16 '11 at 19:09
  • 1
    Initializing variables to nothing is un-Pythonic. Perhaps a bit of an intro course is needed? – chisaipete Jun 16 '11 at 23:21
  • @delnan Partly true, but the problem arises when the script need to run millions of times a day. I have to say python is slower than java in atleast text processing. Even with its C IO implementation. – PhoenixPerson Feb 06 '15 at 13:43

11 Answers11

96

In python, you wouldn't normally do what you are trying to do. But, the below code will do it:

strs = ["" for x in range(size)]
Steve Prentice
  • 23,230
  • 11
  • 54
  • 55
31

In Python, the tendency is usually that one would use a non-fixed size list (that is to say items can be appended/removed to it dynamically). If you followed this, there would be no need to allocate a fixed-size collection ahead of time and fill it in with empty values. Rather, as you get or create strings, you simply add them to the list. When it comes time to remove values, you simply remove the appropriate value from the string. I would imagine you can probably use this technique for this. For example (in Python 2.x syntax):

>>> temp_list = []
>>> print temp_list
[]
>>> 
>>> temp_list.append("one")
>>> temp_list.append("two")
>>> print temp_list
['one', 'two']
>>> 
>>> temp_list.append("three")
>>> print temp_list
['one', 'two', 'three']
>>> 

Of course, some situations might call for something more specific. In your case, a good idea may be to use a deque. Check out the post here: Python, forcing a list to a fixed size. With this, you can create a deque which has a fixed size. If a new value is appended to the end, the first element (head of the deque) is removed and the new item is appended onto the deque. This may work for what you need, but I don't believe this is considered the "norm" for Python.

Community
  • 1
  • 1
pseudoramble
  • 2,541
  • 22
  • 28
9

The simple answer is, "You don't." At the point where you need something to be of fixed length, you're either stuck on old habits or writing for a very specific problem with its own unique set of constraints.

Alex R
  • 2,201
  • 1
  • 19
  • 32
  • 2
    True as advice to a beginner. There are a few cases where it's a valid coice to generate a list of N items and manipulate those items based on indiced without worrying to add items on a by-need basis first. But since half of these manipulate the items, OP's example (with immutable strings) is even less useful. –  Jun 16 '11 at 19:00
  • 1
    I'm just thinking of allocating all the space I need for the array and not having to increase on the run. Allows the code to be neater and me not to have to worry about things going out of bounds – if_zero_equals_one Jun 16 '11 at 19:05
  • 3
    @if_zero_equals_one: (1) It won't go out of bounds because you won't access it by indices, you will iterate it. (2) Lists are over-allocating anyway (appending is amortized O(1)!) and `[item]*n` won't be significantly faster than that (especially considering that both will only take a tiny fraction of overall runtime if you do anything interesting at all). Doubly so if you're going to replace most of the items anyway later on. –  Jun 16 '11 at 19:10
3

The best and most convenient method for creating a string array in python is with the help of NumPy library.

Example:

import numpy as np
arr = np.chararray((rows, columns))

This will create an array having all the entries as empty strings. You can then initialize the array using either indexing or slicing.

Lov Verma
  • 218
  • 4
  • 13
1

But what is a reason to use fixed size? There is no actual need in python to use fixed size arrays(lists) so you always have ability to increase it's size using append, extend or decrease using pop, or at least you can use slicing.

x = [''  for x in xrange(10)]
Artsiom Rudzenka
  • 27,895
  • 4
  • 34
  • 52
1

Are you trying to do something like this?

>>> strs = [s.strip('\(\)') for s in ['some\\', '(list)', 'of', 'strings']]
>>> strs 
['some', 'list', 'of', 'strings']
Gerrat
  • 28,863
  • 9
  • 73
  • 101
1
strlist =[{}]*10
strlist[0] = set()
strlist[0].add("Beef")
strlist[0].add("Fish")
strlist[1] = {"Apple", "Banana"}
strlist[1].add("Cherry")
print(strlist[0])
print(strlist[1])
print(strlist[2])
print("Array size:", len(strlist))
print(strlist)
E. Wang
  • 11
  • 1
  • strlist is an array of sets, which can hold many strings. You need to initiate a set before using methods available in sets. Try the above code to see how the construct works. – E. Wang Dec 10 '20 at 06:50
  • 1
    You may want to add explain. – atline Dec 10 '20 at 07:04
  • This worked for me; but I could use an explanation of how the first line works: `strlist =[{}]*10`. It appears the `*10` is the array length and if I don't include it then my array length is 1, not zero. But does the curly braces in the array declaration mean an array-list of any type, or any length? – benhorgen Aug 31 '21 at 20:46
0

Sometimes I need a empty char array. You cannot do "np.empty(size)" because error will be reported if you fill in char later. Then I usually do something quite clumsy but it is still one way to do it:

# Suppose you want a size N char array
charlist = [' ']*N # other preset character is fine as well, like 'x'
chararray = np.array(charlist)
# Then you change the content of the array
chararray[somecondition1] = 'a'
chararray[somecondition2] = 'b'

The bad part of this is that your array has default values (if you forget to change them).

Shuo Yang
  • 121
  • 1
  • 1
  • 5
0
def _remove_regex(input_text, regex_pattern):
    findregs = re.finditer(regex_pattern, input_text) 
    for i in findregs: 
        input_text = re.sub(i.group().strip(), '', input_text)
    return input_text

regex_pattern = r"\buntil\b|\bcan\b|\bboat\b"
_remove_regex("row and row and row your boat until you can row no more", regex_pattern)

\w means that it matches word characters, a|b means match either a or b, \b represents a word boundary

Engineero
  • 12,340
  • 5
  • 53
  • 75
angela
  • 1
0

The error message says it all: strs[sum-1] is a tuple, not a string. If you show more of your code someone will probably be able to help you. Without that we can only guess.

pillmuncher
  • 10,094
  • 2
  • 35
  • 33
0

If you want to take input from user here is the code

If each string is given in new line:

strs = [input() for i in range(size)]

If the strings are separated by spaces:

strs = list(input().split())
kavitha
  • 11
  • 1