the use of apply could probably be used as a substitute to `*args, **kwargs`

, like this,

```
def apply(f, args, kwargs):
return f(*args, **kwargs) # only need to use * three times here, and not again
```

```
def food(**kwargs): # unfortunately, will have to specify * here
for items in kwargs:
print(f"{kwargs[items]} is a {items}")
dict_1 = {'fruit' : 'cherry', 'vegetable' : 'potato', 'boy' : 'srikrishna'}
# using asterisk
food(**dict_1)
# no asterisk
apply(food, '', dict_1) # if had to specify no keyword arguments
# then would have to pass {}, like apply(f, args, {})
```

there are a few more places where I see the use of `*`

,

I would like to completely avoid using `*`

.

for the common use cases like,

```
2 * 3, 2 ** 3
```

one could use,

```
import operator as op
op.mul(2, 3), op.pow(2, 3)
```

for a case like this,

```
x = {'a': 1, 'b': 2}
y = {'c': 3, 'd': 4}
z = {**x, **y}
```

I could use a ChainMap,

```
from collections import ChainMap
z = ChainMap(x, y)
```

but for cases like these,

```
a, b, *c = [1, 2, 3, 4]
```

the only substitute that appears is to change the list itself

```
a, b, c = [1, 2, [3, 4]]
```

```
numbers = [2, 1, 3, 4, 7]
more_numbers = [*numbers, 11, 18]
```

probably no substitute here, as,

```
more_numbers = [numbers[0:len(numbers)], 11, 18]
more_numbers = [[i for i in numbers], 11, 18]
```

lead to creating new list, (could also have been a set),

```
more_numbers
```

```
[[2, 1, 3, 4, 7], 11, 18]
```

something like this,

```
more_numbers = [i for i in numbers, 11, 18]
```

is invalid