How do I add a suffix (or prefix) elements of an existing list?
Use lapply
and paste0
> lapply(myList, paste0, ".t0")
$list1
[1] "item1.t0" "item2.t0"
$list2
[1] "item3.t0" "item4.t0"
How to add prefix to all the elements of List efficiently?
For one liners, use Java 8 Streams :
List<String> paths = DATA_TYPE.stream().map(c -> flow.value() + c.value()).collect(Collectors.toList());
If you must produce a LinkedList
, you should use a different Collector.
Add a suffix to each dataframe in a list?
If we need to automatically get a named
list
, use mget
with a pattern
argument in the ls
. In the below code, we are getting the value of objects with names that start (^
) with substring 'df' followed by one or more digits (\\d+
) till the end ($
) of the string.
lst1 <- mget(ls(pattern = '^df\\d+$'))
Now, if we use list2env
on the list
created, it would update the same objects in the global environment
list2env(lapply(lst1, transform, new = V1 + 3), .GlobalEnv)
And if we need to create new objects, just change the name of the lst1
names(lst1) <- paste0(names(lst1), "_2018")
list2env(lapply(lst1, transform, new = V1 + 3), .GlobalEnv)
How to add prefix to list items only if prefix is not there already?
Try this.
['p' + x for x in l if x[0] != 'p']
Sorry, that gives the same as yours, if you want all three then try.
['p' + x if x[0] != 'p' else x for x in l]
How to add a suffix (or prefix) to each column name?
You can use a list
comprehension:
df.columns = [str(col) + '_x' for col in df.columns]
There are also built-in methods like .add_suffix()
and .add_prefix()
as mentioned in another answer.
Duplicate strings in a list and add integer suffixes to newly added ones
yield
You can use a generator for an elegant solution. At each iteration, yield twice—once with the original element, and once with the element with the added suffix.
The generator will need to be exhausted; that can be done by tacking on a list
call at the end.
def transform(l):
for i, x in enumerate(l, 1):
yield x
yield f'{x}_{i}' # {}_{}'.format(x, i)
You can also re-write this using the yield from
syntax for generator delegation:
def transform(l):
for i, x in enumerate(l, 1):
yield from (x, f'{x}_{i}') # (x, {}_{}'.format(x, i))
out_l = list(transform(l))
print(out_l)
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
If you're on versions older than python-3.6, replace f'{x}_{i}'
with '{}_{}'.format(x, i)
.
Generalising
Consider a general scenario where you have N lists of the form:
l1 = [v11, v12, ...]
l2 = [v21, v22, ...]
l3 = [v31, v32, ...]
...
Which you would like to interleave. These lists are not necessarily derived from each other.
To handle interleaving operations with these N lists, you'll need to iterate over pairs:
def transformN(*args):
for vals in zip(*args):
yield from vals
out_l = transformN(l1, l2, l3, ...)
Sliced list.__setitem__
I'd recommend this from the perspective of performance. First allocate space for an empty list, and then assign list items to their appropriate positions using sliced list assignment. l
goes into even indexes, and l'
(l
modified) goes into odd indexes.
out_l = [None] * (len(l) * 2)
out_l[::2] = l
out_l[1::2] = [f'{x}_{i}' for i, x in enumerate(l, 1)] # [{}_{}'.format(x, i) ...]
print(out_l)
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
This is consistently the fastest from my timings (below).
Generalising
To handle N lists, iteratively assign to slices.
list_of_lists = [l1, l2, ...]
out_l = [None] * len(list_of_lists[0]) * len(list_of_lists)
for i, l in enumerate(list_of_lists):
out_l[i::2] = l
zip
+ chain.from_iterable
A functional approach, similar to @chrisz' solution. Construct pairs using zip
and then flatten it using itertools.chain
.
from itertools import chain
# [{}_{}'.format(x, i) ...]
out_l = list(chain.from_iterable(zip(l, [f'{x}_{i}' for i, x in enumerate(l, 1)])))
print(out_l)
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
iterools.chain
is widely regarded as the pythonic list flattening approach.
Generalising
This is the simplest solution to generalise, and I suspect the most efficient for multiple lists when N is large.
list_of_lists = [l1, l2, ...]
out_l = list(chain.from_iterable(zip(*list_of_lists)))
Performance
Let's take a look at some perf-tests for the simple case of two lists (one list with its suffix). General cases will not be tested since the results widely vary with by data.
Benchmarking code, for reference.
Functions
def cs1(l):
def _cs1(l):
for i, x in enumerate(l, 1):
yield x
yield f'{x}_{i}'
return list(_cs1(l))
def cs2(l):
out_l = [None] * (len(l) * 2)
out_l[::2] = l
out_l[1::2] = [f'{x}_{i}' for i, x in enumerate(l, 1)]
return out_l
def cs3(l):
return list(chain.from_iterable(
zip(l, [f'{x}_{i}' for i, x in enumerate(l, 1)])))
def ajax(l):
return [
i for b in [[a, '{}_{}'.format(a, i)]
for i, a in enumerate(l, start=1)]
for i in b
]
def ajax_cs0(l):
# suggested improvement to ajax solution
return [j for i, a in enumerate(l, 1) for j in [a, '{}_{}'.format(a, i)]]
def chrisz(l):
return [
val
for pair in zip(l, [f'{k}_{j+1}' for j, k in enumerate(l)])
for val in pair
]
How to add prefix and suffix to a string in python
You can concatenate those onto the string using +.
For example (for Python 2):
print "^"+str1+"$"
Or without + using f-strings in Python 3:
print( f“^{str}$” )
Or if you want to add a prefix to every string in a list:
strings = ['hello', 1, 'bye']
decoratedstrings = [f"^{s}$" for s in strings]
result:
['^hello$', '^1$', '^bye$']
Add prefix and suffix to $@ in bash
I would use shell [ parameter expansion ] for this
$ set -- one two three
$ echo "$@"
one two three
$ set -- "${@/#/pre}" && set -- "${@/%/post}"
$ echo "$@"
preonepost pretwopost prethreepost
Notes
- The
#
matches the beginning - The
%
matches the end - Using double quotes around
${@}
considers each element as a separate word. so replacement happens for every positional parameter
How to join a list elements by ',' using streams with ' as prefix and suffix too
You can actually use Collectors.joining(CharSequence delimiter,CharSequence prefix,CharSequence suffix)
and you can look here for the API.
String values = list.stream().collect(Collectors.joining("','", "'", "'"));
Add prefix and suffix to Collectors.joining() only if there are multiple items present
Yes, this is possible using a custom Collector
instance that will use an anonymous object with a count of items in the stream and an overloaded toString()
method:
public String format(Stream<String> stream) {
return stream.collect(
() -> new Object() {
StringJoiner stringJoiner = new StringJoiner(",");
int count;
@Override
public String toString() {
return count == 1 ? stringJoiner.toString() : "[" + stringJoiner + "]";
}
},
(container, currentString) -> {
container.stringJoiner.add(currentString);
container.count++;
},
(accumulatingContainer, currentContainer) -> {
accumulatingContainer.stringJoiner.merge(currentContainer.stringJoiner);
accumulatingContainer.count += currentContainer.count;
}
).toString();
}
Explanation
Collector
interface has the following methods:
public interface Collector<T,A,R> {
Supplier<A> supplier();
BiConsumer<A,T> accumulator();
BinaryOperator<A> combiner();
Function<A,R> finisher();
Set<Characteristics> characteristics();
}
I will omit the last method as it is not relevant for this example.
There is a collect()
method with the following signature:
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
and in our case it would resolve to:
<Object> Object collect(Supplier<Object> supplier,
BiConsumer<Object, ? super String> accumulator,
BiConsumer<Object, Object> combiner);
- In the
supplier
, we are using an instance ofStringJoiner
(basically the same thing thatCollectors.joining()
is using). - In the
accumulator
, we are usingStringJoiner::add()
but we increment the count as well - In the
combiner
, we are usingStringJoiner::merge()
and add the count to the accumulator - Before returning from
format()
function, we need to calltoString()
method to wrap our accumulatedStringJoiner
instance in[]
(or leave it as is is, in case of a single-element stream
The case for an empty case could also be added, I left it out in order not to make this collector more complicated.
Related Topics
How to Sort a Data Frame by Alphabetic Order of a Character Variable in R
R: How to Get the Percentage Change from Two Different Columns
Combine Two Lists in a Dataframe in R
How to Find the Closest Date to a Given Date
Split Delimited Strings in a Column and Insert as New Rows
How to Disable Scientific Notation
Finding Local Maxima and Minima
Paste Multiple Columns Together
Make the Background of a Graph Different Colours in Different Regions
Generate List of All Possible Combinations of Elements of Vector
Break Dataframe into Smaller Dataframe'S and Save Them
How to Filter Multiple Columns With Same Condition in R
Column Name Changes in R for Loop for Defined Data Frame
Order Discrete X Scale by Frequency/Value
Collapse Text by Group in Data Frame
Interpreting "Condition Has Length ≫ 1" Warning from 'If' Function
Error: Unexpected Symbol/Input/String Constant/Numeric Constant/Special in My Code